Разрешить заполнение только одного поля или другого в модели и администраторе Django - PullRequest
1 голос
/ 17 октября 2019

У меня есть простая модель Django для Группы , которая имеет список Контакты . В каждой группе должно быть либо a Основной контакт ForeignKey или Все контакты BooleanField выбраны, но не оба, а не ни один.

class Group(models.Model):
    contacts = models.ManyToManyField(Contact)
    contact_primary = models.ForeignKey(Contact, related_name="contact_primary", null=True)
    all_contacts = models.BooleanField(null=True)

Как я могу убедиться, что:

  1. Модель не может быть сохранена, если не установлен ни contact_primary, ни all_contacts (но не оба). Я думаю, что было бы путем реализации метода Group.save()? Или это должен быть метод Group.clean() ??

  2. В Django Admin либо отключите другое поле, когда оно выбрано, либо по крайней мере предоставьте осмысленное сообщение об ошибке, если оба или ни один не установлены иадмин пытается его сохранить?

Спасибо!

1 Ответ

2 голосов
/ 17 октября 2019

Самый простой способ - переопределить метод save() вашей модели:

class Group(models.Model):
    contacts = models.ManyToManyField(Contact)
    contact_primary = models.ForeignKey(Contact, related_name="contact_primary", blank=True, null=True)
    all_contacts = models.BooleanField(blank=True, null=True)

    def save(self, *args, **kwargs):
        if self.contact_primary is not None and self.all_contacts is not None:
            raise Exception("some error message here")  
        if self.contact_primary is None and self.all_contacts is None:
            raise Exception("some other error message here")  

        return super().save()

Обратите внимание, что я добавил blank=True в поля вашей модели. Это необходимо, если вы хотите вставить пустые столбцы через администратора или через форму.

Обновление

Если вы хотите поднять ValidationError, вы должны поднятьэто из метода clean() модели. В противном случае вы передадите клиенту ошибку 500, а не сообщение об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...