2012-03-13 168 views
18

我需要将字典保存在模型的字段中。我怎么做?如何在Django数据库模型的字段中存储字典

例如,我有这样的代码:

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

我怎么写“bill_products =”这样可以节省一些随机的产品,从我的产品型号,以这一法案?

这是该法案的模型描述:

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

而且也是该产品的型号说明:

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

如果有什么我要补充只是发表评论。谢谢!

+0

工作到底是什么“蟒蛇数据库模式”?你在使用特定的ORM还是框架?这看起来有点'django-ish' – SingleNegationElimination 2012-03-13 14:58:17

+1

是的,它是Django。我刚刚开始使用它,所以我可能会混淆“Python”与“Django”。我会改变标题。 – 2012-03-13 15:02:52

回答

6

可能最干净的事情是创建另一个“产品”表,并有一个多对多的关系。 (请参阅:https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationships。在文档中,他们使用具有许多配料的披萨示例。)

另一种选择是序列化您的bill_products。在这种情况下,你会做这样的事情:

bill_products = json.dumps([rand_products]) 

这将是外部for循环(尽管在你上面的例子,rand_products只是一个单一的值,所以你需要解决这个问题) 。存储模型中的JSON表示

+0

如果你可以提供一个例子,它会很好。恐怕我不明白如何将我的代码翻译成多对多的关系。我在正确的想法路径与保存在该领域的产品名称数组?或者我可以用更简单的方法做到这一点? – 2012-03-14 17:23:15

+0

@reos你正走在正确的轨道上。以下是一个完整的示例:https://www.djangoproject.com/documentation/0_91/models/many_to_many/ – gdw2 2012-03-14 18:26:04

1

我认为我将创建字段为models.CharField(),然后将字典编码为JSON字符串并将该字符串保存到数据库中。然后,您可以在阅读时将JSON字符串解码为字典。

+0

我添加了Bill的模型描述。 – 2012-03-13 15:14:07

7

一种方便的方法是使用自定义字段类型:

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) 

我保存在此utils的/ fields.py并在我的模型from utils.fields import JSONFielddjango-annoying应用程序中有更多的好东西,这是此片段的来源。

16

我刚刚发现django-jsonfield包,

是一个可重用的Django场,使您可以在您的模型储存验证JSON。

看起来像一个可行的选择,实现你想要的。

+2

感谢您的更新。很高兴知道,即使这个问题在很久以前就已经解决了。 – 2013-05-08 12:09:49

3

如果Postgres的是你的后端,不妨考虑从Django中

+0

谢谢你的回答,但这个问题早已得到解答。而后端是SQLLite – 2015-01-01 14:27:49

6

原生支持使用自定义字段类型是hstore场我首选的解决方案 - 我宁愿有几行自定义代码,而不是支持单个字段类型的整个第三方库。 Tony Abou-Assaleh有一个很好的解决方案,但不适用于较新版本的Django。

这是验证和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 
相关问题