У меня есть пользовательская страница администрирования django, и я хотел бы сделать два поля ForeignKey необязательными в интерфейсе администратора. Я не хочу менять базовую модель.Сделать ForeignKey необязательным в Django Admin?
Это модель:
class IncorporationTicket(models.Model, AdminURL):
ordered_by = models.ForeignKey('Organisation', # organisation which ordered this
null = True,
blank = False, # i.e. can only be null as a result of delete
on_delete = models.SET_NULL)
ordered_by_individual = models.ForeignKey('Individual', # individual at organisation which ordered this
null = True,
blank = False, # i.e. can only be null as a result of delete
on_delete = models.SET_NULL)
(AdminURL является примесь, которая обеспечивает get_absolute_url)
Это ModelAdmin:
class TicketAdmin(admin.ModelAdmin):
readonly_fields = ('ordered', 'charge', 'amount_paid', 'submitted_on')
formfield_overrides = {
models.ForeignKey: {'required': False},
}
def formfield_for_foreignkey(self, db_field, request, **kwargs):
pk = resolve(request.path).args[0] # the request url should only have one arg, the pk
instance = self.get_object(request, pk)
user = request.user
kwargs['required'] = False # will be passed to every field
if db_field.name == "ordered_by_individual":
# queryset should be a union of (a) individual already set on object (b) individual for current user
## None option is provided by admin interface - just need to let field be optional.
if instance.ordered_by_individual:
kwargs["queryset"] = (
Individual.objects.filter(pk = instance.ordered_by_individual.pk) |
user.individual_set.all())
else: kwargs["queryset"] = user.individual_set.all()
elif db_field.name == "ordered_by":
# queryset should be a union of (a) organisation already set (b) any organisations for which user is authorised
try:
individual = user.individual_set.all()[0]
all_orgs = Organisation.all_organisations_for_which_individual_authorised_to_incorporate(individual)
except:
all_orgs = Organisation.objects.none()
if instance.ordered_by:
kwargs["queryset"] = (
Organisation.objects.filter(pk = instance.ordered_by.pk) |
all_orgs)
else: kwargs["queryset"] = all_orgs
return super(type(self), self).formfield_for_foreignkey(db_field, request, **kwargs)
Как вы можете видеть, я попытался используйте как formfield_overrides
, так и formfield_for_foreignkey
, чтобы установить required = False
на FormField, но он не имеет нужного эффекта: при попытке сохранить через интерфейс администратора без настройки (то есть, оставив поле в исходном состоянии пустого состояния), интерфейс администратора показывает ошибку «Это поле необходимо».
Итак, мой вопрос: Как предотвратить предотвращение использования базовой формы из-за определенных полей, при этом также устанавливая выбор в formfield_for_foreignkey
?
@ Марцин, не так ли? Это особая цель 'formfield_for_foreignkey', чтобы переопределить форму. –
Фактическое тестирование показывает, что набор запросов, заданный в 'formfield_for_foreignkey', переопределяется настройками по умолчанию в пользовательской форме. – Marcin
@Marcin это уже не внешний ключ, поэтому нам нужен другой крючок. Альтернативно, как насчет вышеизложенного? Установите обязательный атрибут поля в форме переопределения, и пусть django свяжет это поле с 'models.ForeignKey', поэтому администратор позволяет вам использовать крюк' formfield_for_foreignkey' –