I have two models with one of them defined with a constraint (see "Entities" model below).
I built two forms, one to create new model data and another to update model data. Create form works properly but update form throws an error saying about of already existing items (my constraints is based on the unique combination of two fields). No matter what field I modify within the update form, same error is thrown.
For example, modyfing only "notes" field in an "entity" instance leads to the following error.
Entities with this Name and Company already exists.
How to properly implement my form (and/or models) so that constraint is preserved (an entity with the same name has to be unique within a company) and modification of a non constrained field don't throws an error?
models.py
class Entities(models.Model):
company = models.ForeignKey(Companies, on_delete=models.CASCADE)
name = models.CharField(max_length=50, blank=False, null=False)
notes = models.TextField(blank=True, null=True)
class Meta:
# Constraint here (entity name + company combination name must be unique)
constraints = [models.UniqueConstraint(fields=['name', 'company'], name='unique_company_entity')]
managed = True
db_table = 'entities'
def __str__(self):
object_name = self.name + " " + self.company.name
return object_name
class Companies(models.Model):
name = models.CharField(max_length=50, blank=False, null=False)
notes = models.CharField(max_length=50, blank=True, null=True)
class Meta:
managed = True
db_table = 'companies'
def __str__(self):
object_name = self.name
return object_name
views.py
def entity_edit(request,entity_id):
companies = Companies.objects.all().order_by('name')
entity_id = int(entity_id)
entity = Entities.objects.get(id = entity_id)
if request.method == 'POST':
form = EntityEditForm(request.POST,instance=entity)
if form.is_valid():
post_result = form.save(commit=True)
redirect_url_valid = "/contacts/companies/entities/" + str(entity.id) + "/view/"
return redirect(redirect_url_valid)
else:
form = EntityEditForm(instance=entity)
return render(request,'entity_edit_form.html',{
'companies': companies,
'entity': entity,
'form': form
})
forms.py
class EntityEditForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.label_suffix = ''
self.fields['name'] = forms.CharField(label='Name',widget=forms.TextInput(attrs={ 'class': 'form-control' }))
self.fields['company'] = forms.ModelChoiceField(queryset=Companies.objects.all(),label='Company',required=True,widget=forms.Select(attrs={ 'class': 'form-control' }))
self.fields['notes'] = forms.CharField(label='Notes',required=False,widget=forms.Textarea(attrs={ 'class': 'form-control' }))
class Meta(object):
model = Entities
fields = ('name','company','notes')
# Méthodes de nettoyage des champs du formulaire
def clean_name(self):
name = self.cleaned_data['name']
return name
def clean_company(self):
company = self.cleaned_data['company']
return company
def clean_notes(self):
notes = self.cleaned_data['notes']
return notes
When you save a ModelForm that is initialised with an instance, e.g. MyForm(request.POST, instance=instance_to_update), Django will exclude the instance instance_to_update from its query to check for any uniqueness constraints. See the code.
The code you show in your question is correct, but since you're getting the error, there can only be two explanations:
ModelForm's initialiser (form = EntityEditForm(request.POST)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With