Django admin – изменить текст отображения ForeignKey
Как я могу изменить отображаемый текст при выборе при выборе поля, которое является ForeignKey? Мне нужно отобразить не только имя FK, но и имя его родителя.
Кто-нибудь может дать ключ?
- Привязка к истории моделей Django Admin
- Django admin: как отобразить поле, помеченное как редактируемое = False 'в модели?
- Проблема с ManyToMany Отношения не обновляются сразу после сохранения
- Как я могу ограничить GenericForeignKey Django списком моделей?
- Django admin: как сортировать по одному из пользовательских полей list_display, у которых нет поля базы данных
- Django Admin Показать изображение из Imagefield
- Поле пароля в модели Django
- Пользовательская команда Django и cron
- Фильтр по умолчанию в Django admin
- Перенаправление на admin Сохранить
- Переопределение admin css в django
- Как удалить все таблицы из базы данных с помощью manage.py CLI в Django?
- Переопределить запрос по умолчанию в Django admin
Ну, если вы хотите, чтобы он вступил в силу только в admin, а не во всем мире, тогда вы можете создать собственный подclass ModelChoiceField
, использовать его в пользовательской ModelForm
а затем установить соответствующий class администратора для использования вашей настраиваемой формы. Пример, который имеет FK для модели Person
используемой @Enrique:
class Invoice(models.Model): person = models.ForeignKey(Person) .... class InvoiceAdmin(admin.ModelAdmin): form = MyInvoiceAdminForm class MyInvoiceAdminForm(forms.ModelForm): person = CustomModelChoiceField(queryset=Person.objects.all()) class Meta: model = Invoice class CustomModelChoiceField(forms.ModelChoiceField): def label_from_instance(self, obj): return "%s %s" % (obj.first_name, obj.last_name)
Другой способ сделать это (полезно при изменении набора запросов):
class MyForm(forms.Form): def __init__(self, *args, **kwargs): super(MyForm, self).__init__(*args, **kwargs) self.fields['user'].queryset = User.objects.all() self.fields['user'].label_from_instance = lambda obj: "%s %s" % (obj.last_name, obj.first_name)
‘user’ – это имя поля, которое вы хотите переопределить. Это решение дает вам одно преимущество: вы также можете переопределить запрос (например, вы хотите User.objects.filter (username__startswith = ‘a’))
Отказ от ответственности: решение найдено на http://markmail.org/message/t6lp7iqnpzvlt6qp и проверено.
Более новые версии django поддерживают это, что можно перевести с помощью gettext:
models.ForeignKey(ForeignStufg, verbose_name='your text')
См. https://docs.djangoproject.com/en/1.3/ref/models/instances/#unicode.
class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)
вы должны определить, что вы хотите отобразить в юникодном методе вашей модели (где находится ForeignKey).
С Уважением,
Альтернатива первому ответу:
class InvoiceAdmin(admin.ModelAdmin): class CustomModelChoiceField(forms.ModelChoiceField): def label_from_instance(self, obj): return "%s %s" % (obj.first_name, obj.last_name) def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'person': return self.CustomModelChoiceField(queryset=Person.objects) return super(InvoiceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Я просто обнаружил, что вы можете заменить запрос на другой набор запросов или даже удалить набор запросов и заменить его на список выбора. Я делаю это в change_view.
В этом примере я разрешаю родительскому элементу установить возвращаемое значение, затем захватить определенное поле и установить .choices:
def change_view(self, request, object_id, form_url='', extra_context=None): #get the return value which includes the form ret = super().change_view(request, object_id, form_url, extra_context=extra_context) # let's populate some stuff form = ret.context_data['adminform'].form #replace queryset with choices so that we can specify the "n/a" option form.fields['blurb_location'].choices = [(None, 'Subscriber\'s Location')] + list(models.Location.objects.filter(is_corporate=False).values_list('id', 'name').order_by('name')) form.fields['blurb_location'].queryset = None return ret
Вы также можете выполнить это прямо из вашего экземпляра label_from_instance
используя label_from_instance
. Например:
class InvoiceAdmin(admin.ModelAdmin): list_display = ['person', 'id'] def get_form(self, request, obj=None, **kwargs): form = super(InvoiceAdmin, self).get_form(request, obj, **kwargs) form.base_fields['person'].label_from_instance = lambda obj: "{} {}".format(obj.id, obj.first_name) return form admin.site.register(Invoice, InvoiceAdmin)