Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate ModelForm with unique_together fields in Django?

Tags:

django

How to validate the unique_together error and how to return the custom error message to the html through the view.py. Please help.

model.py:

class Pcq(models.Model):
    product = models.ForeignKey(Product, null=False)
    component = models.ForeignKey(Component, null=False)
    quantity = models.IntegerField('Quantity', null=False)

    class Meta:
        unique_together = ("product", "component")

    def __unicode__(self):
        return self.product.productname

Form.py

class PcqForm(ModelForm):
    class Meta:
        model = Pcq
        fields = ['component', 'quantity']
        exclude = ['product']

Views.py

def pcq_add(request, product_id):
    if request.method == 'POST':
        form = PcqForm(request.POST or None)
        if form.is_valid():
            pcq = form.save(commit=False)
            pcq.product_id = product_id
            pcq.save()
            form = PcqForm()
            successmsg = "Component added successfully! Add another Component..."
            return render(request, 'maps/pcq/pcq_add.html', {'form': form, 'product_id': product_id, 'successmsg': successmsg})
     form = PcqForm()
     return render(request, 'maps/pcq/pcq_add.html', {'form': form, 'product_id': product_id})
like image 915
Rajkumar R Avatar asked Nov 18 '25 20:11

Rajkumar R


1 Answers

You need a custom clean function for the form

class PcqForm(ModelForm):
    class Meta:
        model = Pcq
        fields = ['component', 'quantity']
        exclude = ['product']

    def clean(self):
        cleaned_data = super(PcqForm, self).clean()
        component = cleaned_data.get('component')
        quantity = cleaned_data.get('quantity')

        if component and quantity:
            try:
                Pcq.objects.get(
                    component=component,
                    quantity=quantity,
                )
            except Pcq.DoesNotExist:
                # Yay
                pass
            else
                raise forms.ValidationError(_("Error message goes here"))

UPDATE

Same concept as above but in the view.

def pcq_add(request, product_id):
    if request.method == 'POST':
        form = PcqForm(request.POST or None)
        data = {
            'form': form,
            'product_id': product_id
        }
        if form.is_valid():
            pcq = form.save(commit=False)
            pcq.product_id = product_id

            try:
                pcq.save()
            except IntegrityError:
                # You'll need to check the exception that is raised
                # Handle failed unique_together
                pass
            else:
                form = PcqForm()
                data['successmsg'] =  (
                    "Component added successfully! Add another Component.")
    else:
        form = PcqForm()
        data = {'form': form, 'product_id': product_id}
    return render(request, 'maps/pcq/pcq_add.html', data)

Alternatively:

  • remove the exclude = ['product']
  • on GET pass product_id to the form form = PcqForm(initial_data={'product': product_id})
  • Use the form to validate unique_together (Not sure you even need a custom clean then)
like image 81
rockingskier Avatar answered Nov 21 '25 10:11

rockingskier