[Solved]-Purpose of django.db.models.fields.Field.name argument

9👍

I’ve found name useful if I want a model’s field to have a getter and setter and hide the naming convention introduced by the getter/setter from the Django ORM and the database.

A fairly common pattern in Python is to have the getter and setter be named after the public name of the field, and have the field that holds the value of the field start with an underscore which by convention indicates that it is private. So for instance you’d have a setter and getter named foo and the “private” field for it named _foo:

class Something(object):
    _foo = "some default value"

    @property
    def foo(self):
        return self._foo

    @foo.setter
    def foo(self, val):
        self._foo = val

The code above is barebones. Presumably, in a real-world scenario you’d have additional code in your getter or setter to do some additional work. (Otherwise, there’s no reason for the getter and setter.) Assuming an instance of the class above named instance, you access instance.foo and you do not touch instance._foo because the _foo field is not part of the public API.

If you want to take the pattern above and implement it on a Django model you could just do this:

class MyModel(models.Model):
    _foo = models.TextField()

    @property
    def foo(self):
        return self._foo

    @foo.setter
    def foo(self, val):
        self._foo = val

However, the net result is that your field is known to the Django ORM as _foo and it is stored in a column named _foo in the database. Some people will be okay with this, but in my projects I prefer that the existence of the getter/setter in Python not affect the name of the field elsewhere. In order to have the same name in the Django ORM and for the column name, you can do:

_foo = models.TextField(name="foo")

Doing this will set the name of the field as seen in the Django ORM, so this works:

MyModels.objects.get(foo=...)

Otherwise, you’d have to use the underscore and do MyModels.objects.get(_foo=...). And it also sets the name of the database column so in raw SQL you’d access the column as foo. If you happen to want a different column name, you have to use the db_column argument to set the name: models.TextField(name="foo", db_column="something_else")

👤Louis

0👍

Another example is useful when you want to have one of name from keyword.kwlist, e.g.

class Emails(models.Model):
    from_ = models.CharField(name='from', ...)  # workaround to have `.from` field
    to = models.CharField(...)
    content = models.TextField(...)

since initially it will forbid to set field with name to from with exception: SyntaxError: invalid syntax

Leave a comment