2012-03-13 75 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 
相關問題