Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#33907 closed Bug (needsinfo)

UniqueConstraints voided when using GenericTabularInline

Reported by: Mohamed Alnahhas Owned by: nobody
Component: contrib.contenttypes Version: 4.1
Severity: Normal Keywords:
Cc: Mohamed Alnahhas Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mohamed Alnahhas)

Using Uniquecontraints, I get an error that the object already exist when I create a new object in the Skill_level admin page. However creating the same object through GenericTabularInline gives no errors and the creation is successful when it should not be. So basically Useconstraints is not working at all with GenericTabularInline

Generic field model:

class Skill_level(models.Model):
    level = models.IntegerField(default=1)
    user = models.ForeignKey(User, related_name="skill_level",on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveBigIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

        
    class Meta:
        indexes = [
            models.Index(fields=["content_type", "object_id"]),
        ]
        constraints = [
            UniqueConstraint(fields=['user','content_type', 'object_id'], name='unique_object')
        ]

Generic relation model:

class Subject(models.Model):
    title = models.CharField(max_length=100)
    skill_level = GenericRelation(Skill_level, related_query_name="subject")

    def __str__(self):
        return f"{self.title}"

Admin.py:

class Skill_levelInline(GenericTabularInline):
    model = Skill_level
    extra = 0

class Skill_levelAdmin(admin.ModelAdmin):
    model = Skill_level
    fields = ['user', 'level', 'contnet_type', 'object_id', 'content_object']
    readonly_fields = ["content_object"]

class SubjectAdmin(admin.ModelAdmin):
    inlines = [Skill_levelInline]
    extra = 0

admin.site.register(Skill_level)
admin.site.register(Subject, SubjectAdmin)

Change History (8)

comment:1 by Mohamed Alnahhas, 2 years ago

Description: modified (diff)
Summary: Useconstraints voided in when using GenericTabularInlineUniqueconstraints voided in when using GenericTabularInline

comment:2 by Mohamed Alnahhas, 2 years ago

Cc: Mohamed Alnahhas added

comment:3 by Mohamed Alnahhas, 2 years ago

Version: 4.04.1

comment:4 by Simon Charette, 2 years ago

I didn't test it out but assume this is happening because GenericTabularInline's form is passing an exclude of either {'user','content_type', 'object_id'} the following statement confused me though

However creating the same object through GenericTabularInline gives no errors and the creation is successful when it should not be.

How is this possible, isn't the database crashing due a unique constraint violation?

Can you also reproduce the same issue by using unique_together instead of UniqueConstraint(fields=['user','content_type', 'object_id'], name='unique_object'). If you can then I'm not convinced this should be considered a release blocker.

comment:5 by Mariusz Felisiak, 2 years ago

Resolution: needsinfo
Severity: Release blockerNormal
Status: newclosed
Summary: Uniqueconstraints voided in when using GenericTabularInlineUniqueConstraints voided when using GenericTabularInline

However creating the same object through GenericTabularInline gives no errors and the creation is successful when it should not be. So basically Useconstraints is not working at all with GenericTabularInline.

I cannot reproduce this issue, it crashes for me (as expected) with:

UNIQUE constraint failed: test_one_skill_level.user_id, test_one_skill_level.content_type_id, test_one_skill_level.object_id

If you're also getting IntegrityError than it's a duplicate of #13091.

in reply to:  4 comment:6 by Mohamed Alnahhas, 2 years ago

Replying to Simon Charette:

I didn't test it out but assume this is happening because GenericTabularInline's form is passing an exclude of either {'user','content_type', 'object_id'} the following statement confused me though

However creating the same object through GenericTabularInline gives no errors and the creation is successful when it should not be.

How is this possible, isn't the database crashing due a unique constraint violation?

Can you also reproduce the same issue by using unique_together instead of UniqueConstraint(fields=['user','content_type', 'object_id'], name='unique_object'). If you can then I'm not convinced this should be considered a release blocker.

It is not crashing, the object is created successfully and I get the green success message I can even go to the Skill_level admin page and see the duplicate objects. Opening one of the objects and saving without any changes gives the usual Uniqueconstraints error message. I did try unique together and I was faced with the same exact behavior.

Version 1, edited 2 years ago by Mohamed Alnahhas (previous) (next) (diff)

in reply to:  5 comment:7 by Mohamed Alnahhas, 2 years ago

Replying to Mariusz Felisiak:

However creating the same object through GenericTabularInline gives no errors and the creation is successful when it should not be. So basically Useconstraints is not working at all with GenericTabularInline.

I cannot reproduce this issue, it crashes for me (as expected) with:

UNIQUE constraint failed: test_one_skill_level.user_id, test_one_skill_level.content_type_id, test_one_skill_level.object_id

If you're also getting IntegrityError than it's a duplicate of #13091.

I am not getting any errors at all, I get the green success message that the object was created successfully. I tried this on different models and got the same behavior. I dont know why were not able to reproduce this.

comment:8 by Mariusz Felisiak, 2 years ago

Please attach a sample project. Maybe you're using a database that doesn't support unique constraints (e.g. MySQL < 8), or a 3rd-party database backend. It's difficult to say without a sample project.

Note: See TracTickets for help on using tickets.
Back to Top