【问题标题】:django: ValidationError with UniqueConstraint on Model.Forms, clean()django: ValidationError with UniqueConstraint on Model.Forms, clean()
【发布时间】:2020-03-30 22:21:21
【问题描述】:

我想从 UniqueConstraint 中获取带有 IntegretyError 的页面的表单上的消息 (ValidationError)。

models.py    
class Solicitacao(models.Model):
    '''Modelo de solicitação'''
    solicitante = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
    validators=[])
    disciplina = models.ForeignKey("Disciplina", on_delete=models.CASCADE,
                                   validators=[])
    [..some other data...]
    data_solicitacao = models.DateTimeField(
        ("Data da solicitação"), auto_now_add=True)

    class Meta:
        ordering = ['-data_solicitacao', 'solicitante']
        constraints = [
            models.UniqueConstraint(fields=['solicitante', 'disciplina'], name='unique_solicitação')                                                  
        ]

views.py

 @login_required
def nova_solicitacao(request):
    if request.method == 'POST':
        form = SolicitacaoForm(request.user, request.POST)
        form.instance.solicitante = request.user
        if form.is_valid():
            solicitacao = form.save(commit=False)
            solicitacao.save()
            return redirect(reverse_lazy('cc:solicitacoes'))
    else:       
        form = SolicitacaoForm(request.user)        
    return render(request, 'cc/solicitacao_form.html', {'form': form})

forms.py

class SolicitacaoForm(forms.ModelForm):
       class Meta():
            model = Solicitacao
            fields = ['disciplina', 'justificativa', 'documentos']

    def __init__(self, user, *args, **kwargs):
        super(SolicitacaoForm, self).__init__(*args, **kwargs)
        if not user.is_staff:
            curso = user.curso
        self.fields['disciplina'].queryset = Disciplina.objects.filter(curso=curso)

我相信最好的方法是写 def clean() 但由于 solicitante 不是表单上的字段之一,我无法弄清楚如何访问干净。

我还计划限制每个用户 3 个回答者。我计划在干净的字段中使用基于用户的查询,但我又不知道如何访问它。

【问题讨论】:

    标签: django validation django-forms


    【解决方案1】:
    class SolicitacaoForm(forms.ModelForm):
        class Meta():
            model = Solicitacao
            fields = ['disciplina', 'justificativa', 'documentos']
    
        def __init__(self, user, *args, **kwargs):
            super(SolicitacaoForm, self).__init__(*args, **kwargs)
            # Set the instance's solicitante to the passed user. With this, you no longer have to do it in your views.py as well
            self.instance.solicitante = user
            if not user.is_staff: # note that I moved the queryset filtering inside the if statement to avoid logical errors when user.is_staff is True
                self.fields['disciplina'].queryset = Disciplina.objects.filter(curso=user.curso)
    
        def clean(self, *args, **kwargs):
            super().clean(*args, **kwargs)
            # Get the values
            disciplina = self.cleaned_data['disciplina']
            solicitante = self.instance.solicitante  
    
            # Find the duplicates
            duplicates = Solicitacao.objects.filter(
                disciplina=disciplina, 
                solicitante=solicitante
            )
            if self.instance.pk: # if the instance is already in the database, make sure to exclude self from list of duplicates 
                 duplicates = duplicates.exclude(pk=self.instance.pk)
            if duplicates.exists():
                 raise forms.ValidationError('Solicitacao with similar disciplina and solicitante already exists!')
    
    

    【讨论】:

      猜你喜欢
      • 2013-12-19
      • 2018-12-27
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 2019-11-11
      • 1970-01-01
      相关资源
      最近更新 更多