I have a Django model with a function (on the Python class) that modifies some of its fields.
class TimeStampedModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class MyModel(TimeStampedModel):
user = models.ForeignKey(User, on_delete=models.CASCADE)
a_number = models.FloatField()
some_text = models.CharField(max_length=64)
def MyFunction(self):
self.a_number = 123.123
I can do this, and it works
from django.core.serializers.json import DjangoJSONEncoder
json.dumps(list(MyModel.objects.filter(...).values()), cls=DjangoJSONEncoder)
Now I'd like to call the function MyModel.MyFunction
on all the models before JSON encoding them. I've tried this, but obviously it returns the fields as they are in the database, not modified by MyFunction:
from django.core.serializers.json import DjangoJSONEncoder
mymodels = MyModel.objects.filter(...)
for mymodel in mymodels:
mymodel.MyFunction()
# or mymodel.myfield = somethingelse
json.dumps(list(mymodels.values()), cls=DjangoJSONEncoder)
So I've tried this
from django.core.serializers.json import DjangoJSONEncoder
mymodels = MyModel.objects.filter(...)
_mymodels = []
for mymodel in mymodels:
mymodel.MyFunction()
# or mymodel.myfield = somethingelse
_mymodels.append(mymodel)
json.dumps(_mymodels, cls=DjangoJSONEncoder)
but TypeError: Object of type MyModel is not JSON serializable
.
I've read on other answers that you'd have to either install django rest framework or implement a to_json function on MyModel
.
However, I'd like not to clutter my application to achieve a behavior that is already available. How can I tell django to behave the same way on an array of models that it behaves on a queryset of the same model?
django.forms.models.model_to_dict
did the trick
from django.core.serializers.json import DjangoJSONEncoder
from django.forms.models import model_to_dict
mymodels = MyModel.objects.filter(...)
_mymodels = []
for mymodel in mymodels:
mymodel.MyFunction()
# or mymodel.myfield = somethingelse
_mymodels.append(model_to_dict(mymodel))
json.dumps(_mymodels, cls=DjangoJSONEncoder)
Another alternative is to try using json.dumps(MyModel.objects.filter(...).values(), cls=DjangoJSONEncoder)
, as this will mostly do the same thing as model_to_dict
, but without the overhead of creating model instances (from something like a dict) and then converting them back to dicts.
You may need to write a custom DjangoJSONEncoder
subclass if you use any custom field types, to instruct json.dumps()
how to encode those.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.