Django Admin的内联式解决方案,其中Admin包含ForeignKey到其他模型

时间:2011-06-21 01:02:26

标签: python django django-admin foreign-keys

我有几个Customer人预订Appointment。每个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',)

现在,当管理员通过查看管理员中的约会(按时间排序)浏览计划时,有时他们希望查看有关具有特定约会的客户的信息。现在,他们必须记住客户的名字,从约会导航到客户管理页面,找到记住的客户,然后才能浏览他们的信息。

理想情况下,像管理员内联这样的东西会很棒。但是,如果CustomerInlineAppointment,我似乎只能在Customer管理页面上设置ForeignKey("Appointment")。 (Django特别给我一个错误,说CustomerAppointment没有ForeignKey。有没有人知道类似的功能,但AppointmentForeignKey('Customer')

注意:我简化了模型;实际的客户字段目前除了名称(一些自由文本)之外还有大约10个字段,因此将所有信息放在__unicode__中是不切实际的。

3 个答案:

答案 0 :(得分:7)

使用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源复制更改表单并添加代码以显示客户信息。

答案 1 :(得分:4)

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

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

要将此添加到更改表单,请参阅:Add custom html between two model fields in Django admin's change_form

答案 2 :(得分:1)

在Appointments的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