I need to define a Django model field with the name in
, which is a Python language keyword. This is a syntax error:
class MyModel(models.Model):
in = jsonfield.JSONField()
How can I make this work?
The reason I need this name is when I use django-rest-framework's ModelSerializer
class, field name is used as the key for serialization output, and I thought it might be easier to manipulate django's Model
class instead of ModelSerializer
class to get the output I want.
Generally speaking, you don't. Avoid the use of keywords in your identifiers. The general Python convention is to add an underscore to such names; here that'd be in_
:
class MyModel(models.Model):
in_ = jsonfield.JSONField()
However, Django prohibits names ending in an underscore because the underscore clashes with their filter naming conventions, so you have to come up with a different name still; pick one that still describes your case; I picked contained in rather than in, as a guess to what you want to do here:
class MyModel(models.Model):
contained_in = jsonfield.JSONField()
If you are trying to match an existing database schema, use the db_column
attribute:
class MyModel(models.Model):
contained_in = jsonfield.JSONField(db_column='in')
If you want to be stubborn, in normal classes you could use setattr()
after creating the class to use a string instead of an identifier:
class Foo:
pass
setattr(Foo, 'in', 'some value')
but you'll have to use setattr()
, getattr()
, delattr()
and/or vars()
everywhere in your code to be able to access this.
In Django you'll have the added complication that a models.Model
subclass uses a metaclass to parse out your class members into others structures, and adding an extra field with setattr()
doesn't work without (a lot of) extra work to re-do what the metaclass does. You could instead use the field.contribute_to()
method, calling it after the class has been prepared by Django (technique taken from this blog post):
from django.db.models.signals import class_prepared
def add_field(sender, **kwargs):
if sender.__name__ == "MyModel":
field = jsonfield.JSONField('in')
field.contribute_to_class(sender, 'in')
class_prepared.connect(add_field)
but you have to make sure this hook is registered before you create your model class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With