Подтвердить что ты не робот

Встроенное решение для Django Admin, где Admin содержит ForeignKey для другой модели

У меня есть несколько Customer, которые заказывают Appointment s. Каждый 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',)

Теперь, когда администратор просматривает расписание, просматривая назначения (упорядоченные по времени) в администраторе, иногда они хотят видеть информацию о клиенте, у которого определенная встреча. Прямо сейчас, им нужно будет запомнить имя клиента, перейти от страницы назначения к странице администрирования клиента, найти запомненного Клиента и только затем просмотреть их информацию.

В идеале что-то вроде встроенного админа было бы здорово. Тем не менее, я могу только представить CustomerInline на странице администратора Appointment, если Customer имеет ForeignKey("Appointment"). (Django специально дает мне ошибку, говоря, что Customer не имеет ForeignKey для Appointment). Кто-нибудь знает о подобной функциональности, но когда Appointment имеет ForeignKey('Customer')?

Примечание. Я упростил модели; фактическое поле Customer в настоящее время имеет около ~ 10 полей, кроме имени (некоторый свободный текст), поэтому было бы нецелесообразно помещать всю информацию в __unicode__.

4b9b3361

Ответ 1

Завершение @John answer сверху - укажите, что вы хотели бы видеть в своем списке изменений:

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

И чтобы добавить это в форму изменения, см. Добавить пользовательский html между двумя полями модели в change_form администратора Django

Ответ 2

Нет простого способа сделать это с помощью 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 и добавьте код для отображения информации о клиенте.

Ответ 3

В классе 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