Встроенное решение для 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__
.
Ответы
Ответ 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