Opened 13 months ago

Closed 13 months ago

Last modified 13 months ago

#34979 closed Uncategorized (invalid)

inlineformset_factory sets max_num forms to one even though there is a unique_together constraint

Reported by: Evan Edward Hallein Owned by: nobody
Component: contrib.admin Version: 3.2
Severity: Normal Keywords: inline admin
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description (last modified by Evan Edward Hallein)

I have a unique_together primary key in one of my models. When adding an inline admin for that model, the interface only allows adding one new object. I have tracked it down to code in django/django/forms/models.py:

fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    if fk.unique:
        max_num = 1

this is my model (autogenerated from an existing database):

class TrtMeasurements(models.Model):
    observation = models.OneToOneField('TrtObservations', models.DO_NOTHING, primary_key=True)
    measurement_type = models.ForeignKey(TrtMeasurementTypes, models.DO_NOTHING, db_column='measurement_type')
    measurement_value = models.FloatField()
    comments = models.TextField(blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'trt_measurements'
        unique_together = (('observation', 'measurement_type'),)

While this makes sense for a single unique primary key, it is the wrong behavior for a composite primary key.

Is a fix needed in Django so multiple objects with unique_together primary keys can be added as inlines, or should this be done using custom code?

Change History (4)

comment:1 by Evan Edward Hallein, 13 months ago

Description: modified (diff)

comment:2 by Evan Edward Hallein, 13 months ago

Description: modified (diff)

comment:3 by Evan Edward Hallein, 13 months ago

Resolution: fixed
Status: newclosed

fixed by changing the model to not use the onetoone as a primary key and instead have a separate primary key:

class TrtMeasurements(models.Model):
    id = models.AutoField(primary_key=True)
    observation = models.ForeignKey('TrtObservations', on_delete=models.CASCADE)
    measurement_type = models.ForeignKey(TrtMeasurementTypes, on_delete=models.CASCADE, db_column='measurement_type')
    measurement_value = models.FloatField()
    comments = models.TextField(blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'trt_measurements'
        unique_together = (('observation', 'measurement_type'),)

comment:4 by Mariusz Felisiak, 13 months ago

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