sandeep
sandeep

Reputation: 711

ModelForm validating data for new instance even after passing instance in form

I am creating view for edit data. I am using same model form and html script to create and edit data. In create view I am passing instance in form but form.is_valid is validating data fro new instance.

models.py

class Van(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='vans')
    slug = models.SlugField(max_length=200)
    number_plate = models.CharField(max_length=15, unique=True)
    commercial_name = models.CharField(max_length=100)

forms.py

class VanForm(forms.ModelForm):
    class Meta:
        model = Van
        fields = ('commercial_name', 'number_plate', )

        def clean_number_plate(self):
            number_plate = self.cleaned_data['number_plate']
            van = Van.objects.filter(number_plate=number_plate).exists()

            if van:
                raise forms.ValidationError("A van with this number plate has been registered.")
            return number_plate

views.py

def edit_van_detail(request, slug):
    van = get_object_or_404(Van, slug=slug)
    van_form = VanForm(instance=van)
    if request.method == 'POST':
        van_form = VanForm(request.POST, request.FILES, instance=van)
        if van_form.is_valid():
            return HttpResponseRedirect(reverse('edit_van_detail', args=(van.slug,)))

    context = {
        'van_form': van_form,
    }

    return render(request, 'van/add_van.html', context)

Create is working fine. But on Edit page, when I submit form, it gives unique validation error ("A van with this number plate has been registered.") which I wrote in modelForm. I have done this before without any issue but this time I dont whats wrong.

Upvotes: 0

Views: 44

Answers (1)

Nicolas Appriou
Nicolas Appriou

Reputation: 2331

Your validation method is wrong. You are checking if any Van have this licence plate. The van you are editing has it...

You should remove the model being currently edited.

    def clean_number_plate(self):
        number_plate = self.cleaned_data['number_plate']
        van = Van.objects.filter(number_plate=number_plate).exclude(pk=self.instance.pk).exists()

        if van:
            raise forms.ValidationError("A van with this number plate has been registered.")

This will work even when creating a new model. The primary key of non saved model is None. return number_plate

Upvotes: 1

Related Questions