Cómo almacenar un diccionario en el campo de un modelo de base de datos Django

Necesito guardar un diccionario en el campo de un modelo. ¿Cómo puedo hacer eso?

Por ejemplo tengo este código:

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() 

¿Qué escribo para “bill_products =” para que guarde algunos productos al azar, de mi modelo de producto a esta factura?

Esta es la descripción modelo del proyecto de ley:

 class Bill(models.Model): name = models.CharField(max_length=255) date = models.DateTimeField(auto_now_add=True) products = models.ManyToManyField(Product, related_name="bills") 

Y también la descripción del modelo del producto:

 class Product(models.Model): name = models.CharField(max_length=255) price = models.IntegerField() 

Si hay algo más que debería agregar solo dejar un comentario. ¡Gracias!

Probablemente, lo más limpio sería crear otra tabla de “Productos” y tener una relación de muchos a muchos. (Vea aquí: https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationships . En los documentos utilizan el ejemplo de una pizza con muchos ingredientes).

La otra opción sería serializar tus bill_products. En ese caso, harías algo como:

 bill_products = json.dumps([rand_products]) 

Esto estaría fuera del bucle for (aunque, en su ejemplo anterior, rand_products es solo un valor único, por lo que deberá corregirlo).

Acabo de descubrir el paquete django-jsonfield , que

es un campo reutilizable de Django que le permite almacenar JSON validado en su modelo.

Parece una opción viable para lograr lo que quieres.

Una forma conveniente de almacenar una representación JSON en un modelo es usar un tipo de campo personalizado:

 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) 

Guardé este utils / fields.py y en mi modelo from utils.fields import JSONField . Hay muchas más golosinas en la aplicación django-molesta , que es de donde viene este fragmento de código.

Mi solución preferida es usar un tipo de campo personalizado. Prefiero tener unas pocas líneas de código personalizado que admitir una biblioteca de terceros para un solo tipo de campo. Tony Abou-Assaleh tiene una gran solución, pero no funcionará para las versiones más nuevas de Django.

Esto se verifica para trabajar con 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 

Puede utilizar la serialización / deserialización del módulo pickle:

http://docs.python.org/library/pickle.html

Si postgres es su backend, considere el campo hstore que tiene soporte nativo de django

Creo que crearía el campo como modelos. Campo de campo () y luego codificaría el diccionario como una cadena JSON y guardaría esa cadena en la base de datos. Luego puedes decodificar la cadena JSON de nuevo en un diccionario cuando la lees.