Как я могу создать сложную модель проверки Django для администратора Django? - PullRequest
4 голосов
/ 22 августа 2010

У меня есть следующая модель в Django:

class Bout (models.Model):
    fighter_1 = models.ForeignKey(Fighter, related_name="bout_fighter_1")
    fighter_2 = models.ForeignKey(Fighter, related_name="bout_fighter_2")
    winner = models.ForeignKey(Fighter, related_name="bout_winner", 
        blank=True, null=True, help_text='Leave blank for draw.') 
    date = models.DateField()
    cancelled = models.BooleanField()

Я бы хотел "защищать от дурака" администрацию для ее записей.Кстати, я хочу создать три правила:

  1. Fighter 1 - это не то же самое, что Fighter 2 (что хорошо только для скита Монти Пайтона).*

    Победитель должен быть в бою (т. Е. Fighter 1 или Fighter 2)

  2. Победитель не может быть установлен до начала матча.(В конце концов, это не WWE.)

Все три из этих правил требуют проверки одного поля относительно другого поля в той же записи.Возможно ли сделать это в django, используя нативные методы django или прибегнув к python?

Ответы [ 2 ]

1 голос
/ 22 августа 2010

Краткий ответ: вы можете достичь этого в Django, используя "нативные методы django". Я не уверен, что именно вы подразумеваете под «нативными методами Джанго»; Я предполагаю, что вы имеете в виду звонки в Django API.

Есть несколько способов сделать это. Если ваши пользователи могут создавать только Bout экземпляры, используя предоставленную вами форму, то методы проверки формы могут проверять указанные вами условия. Например ::

class BoutForm(forms.ModelForm):
    class Meta:
        model = Bout

    def clean(self):
        fighter_1 = self.cleaned_data.get('fighter_1')
        fighter_2 = self.cleaned_data.get('fighter_2')
        winner = self.cleaned_data.get('winner')  
        date = self.cleaned_data.get('date')

        if not (fighter_1 and fighter_2 and (fighter_1.id != fighter_2)):
            raise forms.ValidationError("Both fighters cannot be the same")

        if not (winner and (winner.id == fighter_1.id or winner.id == fighter_2.id)):
            raise forms.ValidationError("Winner is not in the fight")

        if not (date and date < datetime.today()):
            raise forms.ValidationError("Winner is not in the fight")

        return self.cleaned_data

Вышеуказанный фрагмент неполный. Вы можете настроить его под свои нужды. Также взгляните на новые растрепанные валидаторы форм Django .

Если, с другой стороны, ваши пользователи могут создавать экземпляры с помощью API (например, путем создания экземпляра класса Bout в своих программах), вам придется выполнить проверку, переопределив метод save() Bout класс.

0 голосов
/ 22 августа 2010

Хотя ответ Маноджа Говиндана выглядит очень хорошо, я также придумал свое собственное решение ... Я включу его здесь на случай, если кто-то посчитает, что мое более короткое решение предпочтительнее:

def clean(self):
    if self.fighter_1 == self.fighter_2:
        raise ValidationError('Fighter 1 can not be Fighter 2.')
    if (self.winner != self.fighter_1) and (self.winner != self.fighter_2):
        raise ValidationError('Winner must be in the bout.')
    if (self.date >= datetime.date.today()) and (self.winner):
        raise ValidationError('Winner can not be set before match.')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...