当我在 Django 中输入 change_list 时不可散列类型 'list'

unhashable type 'list' when i enter on change_list in Django

我搜索了几天来解决这个问题。在接触 admin.py 文件以覆盖 get_queryset 和 get_form 方法后,我 运行 进入不可散列类型 'list' 错误,其中没有关于错误位置的信息位于。我删除了 get_queryset 和 get_form 方法的覆盖,但我仍然得到相同的结果。

[错误] TypeError:无法散列的类型:'list'

当我想通过覆盖 get_queryset 方法来过滤列表时,或者当我尝试输入表单列表的元素时,我发现了这个错误。 我项目中的文件如下:

APP => 主要

admin.py

@admin.register(Notification)
class NotificationsAdmin(admin.ModelAdmin, ExportCsvMixin):
    form = NotificationForm
    add_form = NotificationForm

    list_display = ('title', 'description', 'created_at', 'updated_at',
                    'author')
    fieldsets = (
        ('Information', {
            'fields':
            ('author', 'title', 'subject', 'description', 'signature')
        }),
        ('Images', {
            'fields': ('banner', 'image', 'image2', 'image3')
        }),
        ('Send to', {
            'fields': (
                'send_to',
                'send_all',
            )
        }),
        ('Logs', {
            'fields': ('created_at', 'updated_at')
        }),
    )

    readonly_fields = ('created_at', 'updated_at')
    actions = ['export_as_csv']
    list_per_page = 20

    # list_max_show_all = 30

    def get_form(self, request, obj=None, **kwargs):

        if request.user.groups.filter(name="RSM's").exists():
            self.readonly_fields = ('author', 'created_at', 'updated_at')

        else:
            self.readonly_fields = (
                'created_at',
                'updated_at',
            )
        form = super(NotificationsAdmin, self).get_form(request, **kwargs)

        form.current_user = request.user

        return form

    # get_queryset will return the list of notifications of the user author RSM, else, return all the notifications
    def get_queryset(self, request):
        qs = super(NotificationsAdmin, self).get_queryset(request)
        if request.user.groups.filter(name="RSM's").exists():
            return qs.filter(author=request.user.id)
        else:
            return qs


# Business Segment
# Business Segment
@admin.register(BusinessSegment)
class BusinessSegmentAdmin(admin.ModelAdmin, ExportCsvMixin):
    change_form = BusinessSegmentForm

    list_display = ('name', 'status', 'default_view',
                    'total_visible_companies', 'total_companies',
                    'description', 'get_created_at')
    search_fields = ('name', 'status', 'companies')
    fieldsets = (
        ('General', {
            'fields': ('name', 'description', 'img', 'alt_text')
        }),
        ('Companies', {
            'fields': ('companies', )
        }),
        ('Status and View', {
            'fields': ('status', 'default_view')
        }),
        ('Block Views', {
            'fields': ('blocked_countries', )
        }),
    )
    actions = ['export_as_csv']
    list_per_page = 20
    # list_max_show_all = 30

    ordering = [
        'name',
    ]


# Company Space
@admin.register(CompanySpace)
class CompanySpaceAdmin(admin.ModelAdmin, ExportCsvMixin):

    list_display = ('name', 'status', 'default_view', 'business_area',
                    'website_url', 'get_created_at', 'button_post')
    search_fields = ('name', 'status', 'company_classification',
                     'business_area', 'default_view')
    fieldsets = (('Company Information', {
        'fields': ('name', 'slogan', 'description', 'mini_banner', 'banner',
                   'country', 'business_area')
    }), ('Status and View', {
        'fields': (
            'status',
            'default_view',
        )
    }), ('Presentation or Corporate Brochure', {
        'fields': (
            'brochure_name',
            'brochure',
            'technical_file_name',
            'technical_file',
            'technical_file_name2',
            'technical_file2',
            'technical_file_name3',
            'technical_file3',
            'technical_file_name4',
            'technical_file4',
            'technical_file_name5',
            'technical_file5',
            'technical_file_name6',
            'technical_file6',
            'technical_file_name7',
            'technical_file7',
            'technical_file_name8',
            'technical_file8',
            'technical_file_name9',
            'technical_file9',
            'technical_file_name10',
            'technical_file10',
            'technical_file_name11',
            'technical_file11',
            'technical_file_name12',
            'technical_file12',
        )
    }), ('Videos', {
        'fields': (
            'name_video',
            'url_video',
            'video_language1',
            'name_video2',
            'url_video2',
            'video_language2',
            'name_video3',
            'url_video3',
            'video_language3',
            'name_video4',
            'url_video4',
            'video_language4',
            'name_video5',
            'url_video5',
            'video_language5',
        )
    }), ('Website URL', {
        'fields': ('website_url', )
    }), ('Block Views', {
        'fields': ('blocked_countries', )
    }))
    actions = [
        'export_as_csv',
    ]
    list_per_page = 20
    # list_max_show_all = 12

    ordering = [
        'name',
    ]

    # Faltante que el boton solo aparezca una sola vez, cuando se postea por primera vez la compañia
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('post_company/<int:pk>/',
                 self.post_company,
                 name="admin_post_company"),
        ]
        return my_urls + urls

    def post_company(self, request, pk):
        context = dict(
            # Include common variables for rendering the admin template.
            self.admin_site.each_context(request),
            # Anything else you want in the context...
        )

        company = get_object_or_404(CompanySpace, pk=pk)

        if company:
            if company.status == 'Closed':
                company.status = 'Open'
                company.save()
                if company.default_view == True:
                    clients = Client.objects.all()

                    # ENVIO EMAIL A CLIENTE
                    for client in clients:
                        # SUBJECT
                        subject_client = f'New Manufacturer @ YEM\'s Reserved Area'
                        # MESSAGE TEMPLATE
                        message_client = get_template(
                            "emails/new-sponsor.html").render({
                                'company': company,
                                'url': settings.BASE_URL,
                                'client': client,
                            })

                        mail_client = EmailMessage(
                            subject=subject_client,
                            body=message_client,
                            from_email=settings.EMAIL_HOST_USER,
                            to=[client.email],
                        )
                        mail_client.content_subtype = "html"
                        mail_client.send()

                msg = f'Success: Post Company'
                self.message_user(request, msg, level=messages.INFO)
                return redirect(request.META.get('HTTP_REFERER'))

        else:
            msg = f'Company is null'
            self.message_user(request, msg, level=messages.INFO)
            return redirect(request.META.get('HTTP_REFERER'))
        return redirect(request.META.get('HTTP_REFERER'))

models.py

# Company space
class CompanySpace(models.Model):
    """
    Company space model.
    """
    name = models.CharField(max_length=100, default="")
    status = models.CharField(max_length=10, choices=STATUS, default='Closed')
    default_view = models.BooleanField(default=False)
    company_classification = models.CharField(max_length=150, default="")
    slogan = models.CharField(max_length=150, default="")
    description = models.TextField(max_length=2000, default="")
    mini_banner = models.ImageField(upload_to="mini_banners/", blank=True)
    banner = models.ImageField(upload_to="empresas/")
    country = CountryField(blank_label='(select country)', multiple=True)
    business_area = models.CharField(max_length=80,
                                     choices=BUSINESS_AREA,
                                     default='')
    website_url = models.URLField(max_length=200, default="", blank=True)
    blocked_countries = CountryField(default='Select country',
                                     multiple=True,
                                     null=False,
                                     blank=True)
    first_time = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
   

    REQUIRED_FIELDS = [
        'name',
    ]

    def __str__(self):
        return self.name

    def get_videos(self):
        return self.video_set.all()

    def get_technical_files(self):
        return self.technical_file_set.all()

    def button_post(self):
        company = get_object_or_404(CompanySpace, pk=self.pk)

        if company.status == 'Closed' and company.first_time == True:
            return format_html(
                '<a href="{}" class="btn btn-warning">Post</a>',
                reverse_lazy("admin:admin_post_company", args=[self.pk]))

    button_post.short_description = 'Post company'

    def get_created_at(self):
        return self.created_at.strftime("%d/%m/%Y")

    get_created_at.short_description = 'Created at'


# Product




class Notification(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey('users.User',
                               verbose_name="Author",
                               related_name="users_User",
                               on_delete=models.CASCADE,
                               blank=False,
                               default="")
    banner = models.ImageField(upload_to="notifications/banners/", blank=True)
    description = models.TextField(verbose_name="Message")
    image = models.ImageField(upload_to="notifications/images/",
                              default="",
                              blank=True)
    image2 = models.ImageField(upload_to="notifications/images/",
                               default="",
                               blank=True)
    image3 = models.ImageField(upload_to="notifications/images/",
                               default="",
                               blank=True)
    signature = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    # Agregar una forma de MULTISELECTFIELD
    send_to = models.ManyToManyField('users.Client', blank=True)
    send_all = models.BooleanField(default=False,
                                   verbose_name="Send message to all users")
    subject = models.TextField(max_length=1000, default="", blank=True)

    def __str__(self):
        return self.title 

服务器日志

ERROR:django.request:Internal Server Error: /pre-production/admin/main/businesssegment/1/change/
Traceback (most recent call last):
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/core/handlers/base.py", line 204, in _get_response
    response = response.render()
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 170, in render
    return self._render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 195, in render
    return template.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 172, in render
    return self._render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/defaulttags.py", line 214, in render
    nodelist.append(node.render_annotated(context))
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/defaulttags.py", line 315, in render
    return nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/loader_tags.py", line 195, in render
    return template.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 172, in render
    return self._render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/defaulttags.py", line 214, in render
    nodelist.append(node.render_annotated(context))
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/defaulttags.py", line 214, in render
    nodelist.append(node.render_annotated(context))
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/defaulttags.py", line 315, in render
    return nodelist.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 988, in render
    output = self.filter_expression.resolve(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 671, in resolve
    obj = self.var.resolve(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 796, in resolve
    value = self._resolve_lookup(context)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/template/base.py", line 858, in _resolve_lookup
    current = current()
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/contrib/admin/helpers.py", line 239, in contents
    result_repr = display_for_field(value, f, self.empty_value_display)
  File "*****HIDDEN URL******/3.7/lib/python3.7/site-packages/django/contrib/admin/utils.py", line 385, in display_for_field
    return dict(field.flatchoices).get(value, empty_value_display)
TypeError: unhashable type: 'list'

如有任何帮助,我们将不胜感激。谢谢。

在深入研究问题后,错误是在 html 模板的条件只读字段内的模型表单中生成的。该错误特别出现在 fieldsets.html 文件的 {{field.contents}} 中。 此问题是由于用户分配到的组中缺少权限而产生的。添加该权限后,错误消失了。