我想从UniqueConstraint在带有IntegrityError的页面的表单上获取一条消息(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个anwser。我计划在干净的字段中使用基于用户的查询,但我又不知道如何访问它。
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!')