问题
I need to save a dictionary in a model's field. How do I do that?
For example I have this code:
def create_random_bill(self):
name_chars = re.compile("[a-zA-Z0-9 -_]")
bill_name = "".join(random.choice(name_chars for x in range(10)))
rand_products = random.randint(1,100)
for x in rand_products:
bill_products =
new_bill = Bill.new(name=bill_name, date=datetime.date, products=bill_products)
new_bill.save()
What do I write for "bill_products=" so it saves some random products, from my Product model to this bill?
This is the bill's model description:
class Bill(models.Model):
name = models.CharField(max_length=255)
date = models.DateTimeField(auto_now_add=True)
products = models.ManyToManyField(Product, related_name="bills")
And also the product's model description:
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.IntegerField()
If there's anything else i should add just leave a comment. Thanks!
回答1:
Probably the cleanest thing to do would be to create another "Products" table and have a many-to-many relationship. (See here: https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationships . In the docs they use the example of a pizza having many toppings.)
The other option would be to serialize your bill_products. In that case, you'd do something like:
bill_products = json.dumps([rand_products])
This would be outside of the for loop (although, in your example above, rand_products is only a single value, so you'll need to fix that).
回答2:
I just discovered the django-jsonfield package, which
is a reusable Django field that allows you to store validated JSON in your model.
Looks like a viable option to achieve what you want.
回答3:
One convenient way to store a JSON representation in a model is to use a custom field type:
class JSONField(models.TextField):
"""
JSONField is a generic textfield that neatly serializes/unserializes
JSON objects seamlessly.
Django snippet #1478
example:
class Page(models.Model):
data = JSONField(blank=True, null=True)
page = Page.objects.get(pk=5)
page.data = {'title': 'test', 'type': 3}
page.save()
"""
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if value == "":
return None
try:
if isinstance(value, basestring):
return json.loads(value)
except ValueError:
pass
return value
def get_db_prep_save(self, value, *args, **kwargs):
if value == "":
return None
if isinstance(value, dict):
value = json.dumps(value, cls=DjangoJSONEncoder)
return super(JSONField, self).get_db_prep_save(value, *args, **kwargs)
I saved this utils/fields.py and in my model from utils.fields import JSONField
. There are many more goodies in the django-annoying app, which is where this snippet came from.
回答4:
Using a custom field type is my preferred solution - I'd rather have a few lines of custom code than support an entire 3rd party library for a single field type. Tony Abou-Assaleh has a great solution, but won't work for newer versions of Django.
This is verified to work with Django 1.10.4
import json
from django.db import models
from django.core.serializers.json import DjangoJSONEncoder
class JSONField(models.TextField):
"""
JSONField is a generic textfield that neatly serializes/unserializes
JSON objects seamlessly.
Django snippet #1478
example:
class Page(models.Model):
data = JSONField(blank=True, null=True)
page = Page.objects.get(pk=5)
page.data = {'title': 'test', 'type': 3}
page.save()
"""
def to_python(self, value):
if value == "":
return None
try:
if isinstance(value, str):
return json.loads(value)
except ValueError:
pass
return value
def from_db_value(self, value, *args):
return self.to_python(value)
def get_db_prep_save(self, value, *args, **kwargs):
if value == "":
return None
if isinstance(value, dict):
value = json.dumps(value, cls=DjangoJSONEncoder)
return value
回答5:
You can use serialization/deserialization from pickle module:
http://docs.python.org/library/pickle.html
回答6:
If postgres is your backend, consider the hstore field which has native support from django
回答7:
I think that I would create the field as models.CharField() and then encode the dictionary as a JSON string and save that string into the database. Then you can decode the JSON string back into a dictionary when you read it out.
回答8:
If using PostGres you can store it in natively supported JSON field: https://docs.djangoproject.com/en/dev/ref/contrib/postgres/fields/#jsonfield
Otherwise I'd recommend @ramiro answer with 3rd party lib https://stackoverflow.com/a/16437627/803174
来源:https://stackoverflow.com/questions/9686409/how-to-store-a-dictionary-in-a-django-database-models-field