Code

Opened 4 years ago

Closed 4 years ago

#13079 closed (duplicate)

unique_together constraint is ignored in form generated from model, when inheritance comes into play

Reported by: zimnyx Owned by: nobody
Component: Forms Version: 1.2-beta
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Here you got test case that should pass, but it doesn't because unique_together constraint is ignored.
This happens when constraint is defined in parent class model, and there is child model extending that parent, and form is generated from child model.
Code is simple, just take a look if my explanation is messy.

from django.test import TestCase
from django.db import models
from django import forms
import unittest

class Person(models.Model):
    first_name = models.CharField(max_length=80)
    surname = models.CharField(max_length=80)

    class Meta:
        unique_together = (('first_name', 'surname'),)

class ExtPerson(Person):
    phone = models.CharField(max_length=80)


class PersonForm(forms.ModelForm):
    class Meta:
        model = Person

class ExtPersonForm(forms.ModelForm):
    class Meta:
        model = ExtPerson

class ExtPersonForm1(PersonForm):
    class Meta:
        model = ExtPerson


class TestUniqueTogetherValidation(TestCase):
    def setUp(self):
        Person(first_name='Chuck', surname='Norris').save()

    def tearDown(self):
        Person.objects.all().delete()

    # works as expected
    def test_unique_together_validation_should_work_for_person(self):
        data = {'first_name':'Chuck', 'surname':'Norris'}
        form = PersonForm(data)
        self.assertFalse(form.is_valid())

    # test will prove missing check for unique_together constrains from Person class   
    def test_unique_together_validation_should_work_for_extperson(self):
        data = {'first_name':'Chuck', 'surname':'Norris', 'phone':'1234'}
        form = ExtPersonForm(data)
        self.assertFalse(form.is_valid())

    # test will prove missing check for unique_together constrains from Person class   
    def test_unique_together_validation_should_work_for_extperson_when_model_form_inherits_from_PersonForm(self):
        data = {'first_name':'Chuck', 'surname':'Norris', 'phone':'1234'}
        form = ExtPersonForm1(data)
        self.assertFalse(form.is_valid())

    # test will prove missing check for unique_together constrains from Person class   
    def test_unique_together_validation_return_true_when_data_is_valid_so_writing_to_database_should_work_too(self):
        data = {'first_name':'Chuck', 'surname':'Norris', 'phone':'1234'}
        form = ExtPersonForm(data)
        self.assertTrue(form.is_valid())
        form.save()
Ran 4 tests in 0.219s
FAILED (failures=2, errors=1)

Attachments (0)

Change History (3)

comment:1 Changed 4 years ago by kmtracey

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to duplicate
  • Status changed from new to closed

I believe this is #12881.

comment:2 Changed 4 years ago by kmtracey

  • Resolution duplicate deleted
  • Status changed from closed to reopened

I'm wrong. The patch on #12881 does not fix this case, it appears the unique_together constraint is not considered for the child model. I suspect fixing this will require first fixing #12881 though.

comment:3 Changed 4 years ago by kmtracey

  • Resolution set to duplicate
  • Status changed from reopened to closed

New patch on #12881 attempts a comprehensive fix of inherited unique constraints, so this will be fixed by #12881 even though the original problem report is a bit different.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.