Jag Singh
Jag Singh

Reputation: 145

Django - meta class

When amending a meta class to include a unique_together and trying to makemigrations, I keep getting "No changes detected" which I'm presuming isn't expected behaviour. ERROR #1

I did try and remove the migration for that particular model and makemigration but that still doesn't include this meta class attribute.

I can in fact force a migration by changing other aspects of the model and then manually editing the migration.py which works. However when using the model in a tabularinline and overriding the save_formset I get the "Enum value with this Enum code already exists".ERROR #2

Dirty message: Unique constraint screenshot

Model.py

class EnumValue(models.Model):
    enum_code = models.CharField(max_length=16, unique=True)
    enum_value_en = models.CharField(max_length=40, verbose_name='English VALUE')
    lowercase_enum_value_en = models.CharField(max_length=500, db_index=True)
    enum = models.ForeignKey(Enum, db_index=True, verbose_name='Enum')
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)
    created_by = models.ForeignKey(User, related_name='enumvalue_created_by_user')
    modified_by = models.ForeignKey(User, related_name='enumvalue_updated_by_user')

class Meta:
    unique_together = (('enum_code', 'enum'),)
    ordering = ('lowercase_enum_value_en',)

def __unicode__(self):
    return self.enum_value_en

class Meta:
    verbose_name_plural = 'Enum Values'

Migration.py

class Migration(migrations.Migration):

dependencies = [
    ('dq', '0031_enum_enumvalue'),
]

operations = [
    migrations.AlterUniqueTogether(
        name='enumvalue',
        unique_together=set([('enum_code', 'enum')]),
    ),
]

**Admin - tabularinline **

def save_formset(self, request, form, formset, change):
    if formset.is_valid: # ensures no blank forms are submitted
        instances = formset.save(commit=False) # gets instance from memory and add to it before saving it
        for obj in formset.deleted_objects:
            obj.delete()
        for instance in instances:
            instance.modified_by = request.user
            instance.created_by = request.user
            instance.lowercase_enum_value_en = instance.enum_value_en.lower() # no need to get clean data from "form"
            instance.save()
        formset.save()

I'm using Django v1.8.4

Upvotes: 1

Views: 430

Answers (2)

knbk
knbk

Reputation: 53669

Your EnumValue class has two Meta classes. This behaves just like reassigning a variable: the first class definition is lost, and only the second class definition remains. You need to merge these together into a single class.

class EnumValue(models.Model):
    ...
    class Meta:
        unique_together = (('enum_code', 'enum'),)
        ordering = ('lowercase_enum_value_en',)
        verbose_name_plural = 'Enum Values'

    def __unicode__(self):
        return self.enum_value_en

Upvotes: 1

RemcoGerlich
RemcoGerlich

Reputation: 31260

I think the cause is that your enum_code field already has unique=True by itself. Thus it's automatically unique together with any other field without needing a migration, and your error is also explained.

Upvotes: 0

Related Questions