@Eldalex

Как сделать валидацию в админ панели django?

Добрый день! подскажите как сделать валидацию в админ панели джанго:
схема такая:
есть модель с ответами на вопросы теста. она подключается inline к самим вопросам.
class AnswerAdm(admin.StackedInline):
model = Answers
fields = ('question_id', 'aswer_text', 'true_answer',)
readonly_fields = ('question_id',)

class TestquestionAdmin(admin.ModelAdmin):
list_display = ('question_id', 'test_id', 'question_text',)
list_display_links = ('question_id',)
inlines = [AnswerAdm, ]

в админке выглядит так:
638f932e102e4001726538.png
можно ли как то сделать валидацию полей формы?
чтобы например у трёх ответов не стояло одновременно три чекбокса "Верный ответ"
  • Вопрос задан
  • 49 просмотров
Пригласить эксперта
Ответы на вопрос 2
ma4akk
@ma4akk
Да, вы можете сделать валидацию полей формы в админ панели Django. Для этого вам нужно будет использовать специальный класс ModelForm и переопределить метод clean() для проверки полей формы.

Например:
class AnswerForm(forms.ModelForm):
    class Meta:
        model = Answers
        fields = ('question_id', 'aswer_text', 'true_answer',)
        readonly_fields = ('question_id',)

    def clean(self):
        cleaned_data = super().clean()
        true_answer = cleaned_data.get("true_answer")
        if true_answer:
            # Проверяем, что у других ответов не установлен чекбокс "Верный ответ"
            answers = Answer.objects.filter(question_id=cleaned_data.get("question_id"))
            for answer in answers:
                if answer.true_answer:
                    raise ValidationError("Нельзя установить более одного верного ответа")
        return cleaned_data

class AnswerAdm(admin.StackedInline):
    form = AnswerForm
    model = Answers
    fields = ('question_id', 'aswer_text', 'true_answer',)
    readonly_fields = ('question_id',)

class TestquestionAdmin(admin.ModelAdmin):
    list_display = ('question_id', 'test_id', 'question_text',)
    list_display_links = ('question_id',)
    inlines = [AnswerAdm, ]
Ответ написан
@Eldalex Автор вопроса
А можете в кратце пояснить как работает?
я прокомментировал как понял, если не так, поправьте пожалуйста
def clean(self):  #вызывается столько раз, сколько есть ответов на форме забирая по очереди каждый ответ
        cleaned_data = super().clean() #забирает данные из очередного answers_set
        true_answer = cleaned_data.get("true_answer") #получает состояние чекбокса
        if true_answer: # если он взведён
            # Проверяем, что у других ответов не установлен чекбокс "Верный ответ"
            answers = Answer.objects.filter(question_id=cleaned_data.get("question_id")) # собираем информацию из БД по уже имеющимся записям.
            for answer in answers: #если хотя бы в одной из них true вызываем ValidationError
                if answer.true_answer:
                    raise ValidationError("Нельзя установить более одного верного ответа")
        return cleaned_data # иначе возвращаем данные

вот тут возникает вопрос.
все данные формы сверяются с БД.
Если создать новый вопрос и насовать в него ответов и все отметить как true_answer они все лягут в БД, т.к. на момент проверки там не существует записей.
Обратная ситуация, если надо поменять ошибочный чекбокс. мы убираем первый ответ, помечаем второй. и снова перед тем как всё ляжет в БД оно сверяется с уже существующими записями. а там стоит первый. соответственно снова всегда ValidationError.
можно ли как то сверять именно данные формы в пределах одного вызова функции?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы