Django Admin的类内联解决方案,其中Admin包含其他模型的外键

relj7zay  于 2023-02-17  发布在  Go
关注(0)|答案(4)|浏览(148)

我有几个预订AppointmentCustomer。每个Appointment正好有一个客户,尽管一个客户可以预订在不同时间发生的多个约会。

class Customer(model.Model):
    def __unicode__(self):
        return u'%s' % (self.name,)
    name = models.CharField(max_length=30)
    # and about ten other fields I'd like to see from the admin view.

class Appointment(models.Model):
    datetime = models.DateTimeField()
    customer = models.ForeignKey("Customer")
    class Meta:
        ordering = ('datetime',)

现在,当管理员通过查看管理中的“约会”(按时间排序)来浏览日程表时,有时他们希望查看有关具有特定约会的客户的信息。现在,他们必须记住客户的姓名,从“约会”导航到“客户”管理页面,找到记住的客户,然后才能浏览他们的信息。
理想情况下,类似管理内联的东西会很棒。然而,如果CustomerForeignKey("Appointment"),我似乎只能在Appointment管理页面上创建CustomerInline。(Django特别给了我一个错误,说Customer没有Appointment的外键)。有人知道类似的功能吗,但是当AppointmentForeignKey('Customer')时?
注:我简化了模型;实际的Customer字段目前除了名称(一些自由文本)之外还有大约10个字段,因此将所有信息都放在__unicode__中是不切实际的。

eufgjt7s

eufgjt7s1#

在django中没有简单的方法来做到这一点,内联被设计成向后跟踪关系。
最好的替代方法可能是提供一个指向用户对象的链接,但在列表视图中这是非常简单的:
向约会模型添加一个方法,如下所示:

def customer_admin_link(self):
    return '<a href="%s">Customer</a>' % reverse('admin:app_label_customer_change %s') % self.id
customer_admin_link.allow_tags = True
customer_admin_link.short_description = 'Customer'

然后在ModelAdmin中添加:

list_display = (..., 'customer_admin_link', ...)

另一个解决方案是定义一个自定义的管理模板,这样你就可以做任何事情。下面是我以前用过的一个指南来解释:http://www.unessa.net/en/hoyci/2006/12/custom-admin-templates/
基本上从Django源代码中复制更改表单并添加代码来显示客户信息。

wnavrhmk

wnavrhmk2#

完成上面@John的回答-定义您希望在更改列表中看到的内容:

return '<a href="%s">%s</a>' % (
                     reverse('admin:applabel_customer_change', (self.customer.id,)),
                     self.customer.name # add more stuff here
             )

要将其添加到变更表单中,请参见:在Django admin的change_form中的两个模型字段之间添加自定义html

omjgkv6w

omjgkv6w3#

在约会的ModelAdmin类中,应声明以下方法:

class MySuperModelAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):

    if obj:
      # create your own model admin instance here, because you will have the Customer's
      # id so you know which instance to fetch
      # something like the following
      inline_instance = MyModelAdminInline(self.model, self.admin_site)
      self.inline_instances = [inline_instance]

    return super(MySuperModelAdmin, self).get_form(request, obj, **kwargs)

有关详细信息,请浏览该函数的源代码,以给予您将访问哪些内容。
https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L423

wtlkbnrh

wtlkbnrh4#

有一个库可以使用。https://github.com/daniyalzade/django_reverse_admin
但如果你想使用链接到显示表中的对象,你可以喜欢这个代码:

def customer_link(self, obj):
    if obj.customer:
        reverse_link = 'admin:%s_%s_change' % (
            obj.customer._meta.app_label, obj.customer._meta.model_name)
        link = reverse(reverse_link, args=[obj.customer.id])
        return format_html('<a href="%s">More detail</a>' % link)
    return format_html('<span >-</span>')

customer_link.allow_tags = True
customer_link.short_description = 'Customer Info'

在列表显示中:

list_display = (...,customer_link,...)

相关问题