David
David

Reputation: 69

Django unique_together does not work: "refers to the non-existent field"

Creating a model in Django, I need to make unique the combination of two integer fields:

class example(models.Model):
    lenght = models.PositiveSmallIntegerField
    position = models.PositiveSmallIntegerField
    otherfield = models.ForeignKey('onetable')
    otherfield2 = models.ForeignKey('anothertable')

    class Meta:
        unique_together = (("lenght", "position"),)

So when I sync the database I receive the follow error message:

Executing manage.py syncdb SystemCheckError: System check identified some issues:

ERRORS:
prj.CodeBlock: (models.E012) 'unique_together' refers to the non-existent field 'lenght'.
prj.CodeBlock: (models.E012) 'unique_together' refers to the non-existent field 'position'.
The Python REPL process has exited
>>> 

I find out if I change the field type to "charfield" I do not receive any error message:

class example(models.Model):
    lenght = models.CharField(max_length=8)
    position = models.CharField(max_length=8)
    otherfield = models.ForeignKey('onetable')
    otherfield2 = models.ForeignKey('anothertable')

    class Meta:
        unique_together = (("lenght", "position"),)

Why I cannot make unique the combination of integer fields?

Upvotes: 2

Views: 2214

Answers (1)

Luis Masuelli
Luis Masuelli

Reputation: 12333

Because you did not declare (instantiate) the integer fields (you just referenced their classes):

class example(models.Model):
    lenght = models.PositiveSmallIntegerField
    position = models.PositiveSmallIntegerField

length and position are not field instances, but field classes. Try instantiating them to be actually existent fields in the table:

class example(models.Model):
    lenght = models.PositiveSmallIntegerField()
    position = models.PositiveSmallIntegerField()

In its metaclass, Django detects and enumerates field instances (i.e. by running isinstance(v, Field)) and create their columns. You can have any value declared in your class (methods are attributes; perhaps your class has custom exceptions or constant values for a choices= argument, ...), but only Field instances will be enumerated. This applies to field classes: Django does not treat them specially: perhaps you declare a custom Field class as an inner class in your model (intended to be used only in your model), and you would not expect it become just a field... so that's the reason why Django does not convert references to field classes to references to field instances.

You must be explicit. Perhaps you forgot the parenthesis.

Upvotes: 3

Related Questions