Убедитесь, что 2 поля выбора в записи не равны Django - PullRequest
1 голос
/ 17 июня 2020

У меня есть модель с 2 CharFields, выбранными из почти того же списка вариантов. Они одинаковы, за исключением того, что для второго наклона есть опция «Нет».

class Pawn(models.Model):
    primary_inclination = models.CharField(max_length=30, choices=PRIMARY_INCLINATION_CHOICES)
    secondary_inclination= models.CharField(max_length=30, choices=SECONDARY_INCLINATION_CHOICES)

Я хочу убедиться, что одно и то же значение нельзя выбрать для обоих полей. Например, если мой выбор выбран из A, B, C, то A и B подходят, а A и A - нет. Это нормально, если у другой пешки также есть A и B.

Некоторые вещи, которые я изучил:

  • Указание уникальных полей в Meta, но это делает склонности выбирается только 1 пешкой

  • уникально_всего, никакая другая пешка не может иметь одинаковые значения для двух полей

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Рекомендуется проводить проверку как можно ближе к источнику. Реализация таких методов, как clean или save_model (в пределах Django Admin) проверяет на уровне сервера, что является последней линией защиты. Вы также можете использовать JavaScript, чтобы отключить кнопку отправки формы, если только выбранные наклонности не отличаются. Другой метод - использовать проверку формы в представлении:

from django.core.exceptions import ValidationError
from django import forms

class PawnForm(forms.Form):
    primary_inclination = forms.CharField()
    secondary_inclination = forms.CharField()

    def clean(self):
        # Assume posted data includes pinc (primary_inclination) and sinc (secondary inclination)
        if 'pinc' in self.cleaned_data and 'sinc' in self.cleaned_data:
            if self.cleaned_data['pinc'] == self.cleaned_data['sinc']:
                raise forms.ValidationError(
                    ("Primary and Secondary inclinations must be different"))
        else:
            raise forms.ValidationError(
                ("Both Primary and Secondary inclinations required")) 
        return self.cleaned_data

По вашему мнению, вы можете иметь что-то вроде:

from django.shortcuts import render, redirect
from django.urls import reverse
from django.views.generic.edit import FormView


class PawnView(FormView):

    def get(self, request):
        context = {}
        context['form'] = PawnForm(request.POST or None)
        return render(request, 'pawn.html', context)

    def post(self, request):
        context = {}
        form = PawnForm(request.POST or None)
        context['form'] = form
        if form.is_valid():
            # Form is valid...go ahead and process data
            new_pawn = Pawn.create(form.cleaned_data.get(‘pinc’), form.cleaned_data.get(‘sinc’)
            return redirect(reverse('pawn-view'))
        else:
            for k, v in form.errors.items():
                # Retrieve the text of our validation error or you can simply use form.errors
                context['error'] = v
            return render(request, 'pawn.html', context)

Вы можете показать ошибку проверки в закладке. html очень легко:

<div class="pawn-error">
    <h3>{{ error | striptags }}</h3>
</div>
2 голосов
/ 17 июня 2020

Вы можете использовать метод clean в своей модели, чтобы добавить настраиваемую проверку и вызвать ValidationError, если поля совпадают:

from django.core.exceptions import ValidationError

class Pawn(models.Model):
    primary_inclination = models.CharField(max_length=30, choices=PRIMARY_INCLINATION_CHOICES)
    secondary_inclination= models.CharField(max_length=30, choices=SECONDARY_INCLINATION_CHOICES)

    def clean(self):
        if self.primary_inclination == self.secondary_inclination:
            raise ValidationError('Primary and secondary inclinations should be different.')
...