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")
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
- Django limit_choices_to on user group
- Django with gunicorn and nginx: HTTP 500 not appearing in log files