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

发布于 2024-11-16 20:54:43 字数 1037 浏览 2 评论 0原文

我有几个预订约会客户。每个约会只有一位客户,但客户可以预订在不同时间发生的多个约会。

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__ 中是不切实际的。

I have several Customers who book Appointments. Each Appointment has exactly one customer, though a customer can be booked for multiple appointments occurring at different times.

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',)

Now when an admin goes to browse through the schedule by looking at the Appointments (ordered by time) in the admin, sometimes they want to see information about the customer who has a certain appointment. Right now, they'd have to remember the customer's name, navigate from the Appointment to the Customer admin page, find the remembered Customer, and only then could browse their information.

Ideally something like an admin inline would be great. However, I can only seem to make a CustomerInline on the Appointment admin page if Customer had a ForeignKey("Appointment"). (Django specifically gives me an error saying Customer has no ForeignKey to Appointment). Does anyone know of a similar functionality, but when Appointment has a ForeignKey('Customer')?

Note: I simplified the models; the actual Customer field currently has about ~10 fields besides the name (some free text), so it would be impractical to put all the information in the __unicode__.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

望她远 2024-11-23 20:54:43

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

There is no easy way to do this with django. The inlines are designed to follow relationships backwards.

Potentially the best substitute would be to provide a link to the user object. In the list view this is pretty trivial:

Add a method to your appointment model like:

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'

Then in your ModelAdmin add:

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

Another solution to get exactly what you're looking for at the cost of being a bit more complex would be to define a custom admin template. If you do that you can basically do anything. Here is a guide I've used before to explain:
http://www.unessa.net/en/hoyci/2006/12/custom-admin-templates/

Basically copy the change form from the django source and add code to display the customer information.

国产ˉ祖宗 2024-11-23 20:54:43

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

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

要将其添加到更改表单中,请参阅:在两个模型之间添加自定义html Django 管理员的change_form 中的字段

Completing @John's answer from above - define what you would like to see on the your changelist:

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

And to add this to the change form, see: Add custom html between two model fields in Django admin's change_form

枯寂 2024-11-23 20:54:43

在约会的 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

In the ModelAdmin class for your Appointments, you should declare the following method:

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)

For more information, browser the source for that function to give you an idea of what you will have access to.

https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L423

合约呢 2024-11-23 20:54:43

有一个库你可以使用它。
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中:

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

There is a library you can use it.
https://github.com/daniyalzade/django_reverse_admin

But if you want to use link to object in showing table you can like this code:

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'

And in list_display:

list_display = (...,customer_link,...)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文