【问题标题】:Django admin - How to add request.user as default vaule for a Inline model?Django admin - 如何添加 request.user 作为内联模型的默认值?
【发布时间】:2021-06-05 03:24:30
【问题描述】:

我编写了一个由 2 个模型组成的小型支持应用程序,请参见下文。 当我在 django 管理面板上回答支持工单时,我并不总是想为我添加到工单的每个回复手动设置作者姓名。相反,我想要我自动设置为作者的 request.user 作为初始值。遗憾的是,我无法在 django 文档中找到任何似乎可以解决此问题的解决方案...

admin.py

class SupportTicketRepliesInline(admin.TabularInline):
    model = SupportTicketReplies
    extra = 0
    min_num = 1

class SupportTicketsAdmin(admin.ModelAdmin):
    list_display = ['requester', 'creation_date', 'status', 'category', 'subject']
    ordering = ['-creation_date']
    list_filter = ['creation_date']
    inlines = [
        SupportTicketRepliesInline,
    ]


admin.site.register(SupportTickets, SupportTicketsAdmin)

models.py

...
class SupportTickets(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    requester = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
    category = models.IntegerField(choices=TICKET_CATEGORY, verbose_name='Ticket Category')
    subject = models.CharField(max_length=30)
    description = models.TextField(max_length=2000, blank=False, verbose_name='Problem description')
    status = models.IntegerField(choices=STATUS_OF_TICKET, verbose_name='Ticket Status', default=2)
    creation_date = models.DateTimeField(auto_now_add=True, blank=False)

    def publish(self):
        self.creation_date = timezone.now()
        self.save()
    
    class Meta:
        verbose_name = "Support Ticket"
        verbose_name_plural = "Support Tickets"
        ordering = ['-creation_date']

models.py

class SupportTicketReplies(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ticket = ForeignKey(SupportTickets, related_name='replies', on_delete=models.CASCADE)
    author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Author', blank=True)
    content = models.TextField(verbose_name="Content", max_length=2000)
    creation_date = models.DateTimeField(auto_now_add=True, blank=False)

    class Meta:
        verbose_name = "Ticket Reply"
        verbose_name_plural = "Ticket Replies"
        ordering = ['creation_date']

【问题讨论】:

    标签: python django django-admin


    【解决方案1】:

    我认为您需要的是: https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey 它看起来像:

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "author":
            self.fields['author'].queryset = UserModel.objects.filter(id=request.usermodel.id)
    

    您还应该从模型中删除 blank=True。

    或者你可以添加到你的内联类作为初始值:

     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['author'].initial = self.request.user
    

    【讨论】:

    • 您好,感谢您的回复。我尝试了您的解决方案,但总是失败并出现以下错误: TypeError: 'NoneType' object is not subscriptable 这是我的查询:self.fields['author'].queryset = User.objects.get(id=request.user. id) 返回有效的 UUID,我可以确认!
    • User.objects.get(id=request.user.id) 不返回查询集,而是返回单个对象。
    • 那我根本不明白......除了你的解决方案指出 admin.ModelAdmin 但我在 admin.TabularInline
    • 它也可以在内联中使用它。 docs.djangoproject.com/en/3.1/ref/contrib/admin/… 重点是,您将查询集限制为仅登录 request.user。 (所以它的一个用户)但仍然需要作为查询集传递。(si .filter 是必需的)
    • 你看到我的解决方案了吗?
    【解决方案2】:

    以下对我有用:

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "author":
            author = request.user
            if author:
                kwargs['initial'] = author.pk
        return super(SupportTicketRepliesInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
    

    在 admin.TabularInline 或 admin.StackedInline

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 2015-06-29
      • 2017-10-26
      • 2012-04-19
      • 2011-07-30
      • 1970-01-01
      相关资源
      最近更新 更多