2012-03-13 29 views
18

Tôi cần lưu từ điển vào trường của mô hình. Làm thế nào để làm điều đó?Cách lưu trữ từ điển trong trường mô hình cơ sở dữ liệu Django

Ví dụ tôi có mã này:

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

để tôi viết gì cho "bill_products =" vì vậy nó tiết kiệm một số sản phẩm ngẫu nhiên, từ mô hình sản phẩm của tôi vào hóa đơn này?

Đây là dự luật mô tả mô hình:

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

Và cũng mô hình của sản phẩm mô tả:

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

Nếu có bất cứ điều gì khác tôi nên thêm chỉ để lại nhận xét. Cảm ơn!

+0

What the heck là một "mô hình cơ sở dữ liệu trăn"? Bạn đang sử dụng một ORM cụ thể hoặc khuôn khổ? điều này có vẻ hơi 'django-ish' – SingleNegationElimination

+1

Vâng, đó là Django. Tôi chỉ bắt đầu làm việc với nó vì vậy tôi có thể trộn lên "Python" với "Django". Tôi sẽ thay đổi tiêu đề. –

Trả lời

6

Có lẽ điều sạch sẽ nhất là tạo một bảng "Sản phẩm" khác và có mối quan hệ nhiều-nhiều. (Xem tại đây: https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationships. Trong tài liệu, họ sử dụng ví dụ về một bánh pizza có nhiều lớp trên bề mặt.)

Tùy chọn khác sẽ là sắp xếp hàng loạt hóa đơn của bạn. Trong trường hợp đó, bạn muốn làm điều gì đó như:

bill_products = json.dumps([rand_products]) 

Đây sẽ là bên ngoài của vòng lặp for (mặc dù, trong ví dụ của bạn ở trên, rand_products chỉ là một giá trị duy nhất, vì vậy bạn sẽ cần phải khắc phục điều đó) .

+0

Nếu bạn có thể cung cấp một ví dụ, nó sẽ rất đẹp. Tôi sợ tôi không hiểu chính xác cách dịch một mối quan hệ nhiều - nhiều như thế nào với mã của tôi. Tôi đang trên con đường ý tưởng đúng với tiết kiệm một mảng với tên sản phẩm trong lĩnh vực đó? Hoặc tôi có thể làm điều đó theo một cách tiếp cận đơn giản hơn? –

+0

@reos Bạn đang đi đúng hướng. Dưới đây là ví dụ đầy đủ: https://www.djangoproject.com/documentation/0_91/models/many_to_many/ – gdw2

1

Tôi nghĩ rằng tôi sẽ tạo trường như mô hình.CharField() và sau đó mã hóa từ điển dưới dạng chuỗi JSON và lưu chuỗi đó vào cơ sở dữ liệu. Sau đó, bạn có thể giải mã chuỗi JSON trở lại từ điển khi bạn đọc nó.

+0

Tôi đã thêm mô tả mô hình của Bill. –

7

Một cách thuận tiện để lưu trữ một đại diện JSON trong một mô hình là sử dụng một loại trường tùy chỉnh:

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) 

tôi lưu này utils/fields.py và trong mô hình của tôi from utils.fields import JSONField. Có nhiều tính năng khác trong ứng dụng django-annoying, đây là nơi mà đoạn mã này đến từ đó.

16

Tôi chỉ phát hiện ra django-jsonfield gói, trong đó

là một Django lĩnh vực tái sử dụng mà cho phép bạn lưu trữ xác nhận JSON trong mô hình của bạn.

Có vẻ như một tùy chọn khả thi để đạt được những gì bạn muốn.

+2

Cảm ơn bạn đã cập nhật. Thật tuyệt khi biết, ngay cả khi vấn đề này đã được sửa chữa từ lâu rồi. –

3

Nếu postgres là phụ trợ của bạn, hãy xem xét lĩnh vực hstore trong đó có hỗ trợ có nguồn gốc từ django

+0

Cảm ơn bạn đã trả lời, nhưng câu trả lời này từ lâu đã được giải đáp và giải quyết. Và phụ trợ cho điều này là SQLLite –

6

Sử dụng một loại lĩnh vực tùy chỉnh là của tôi giải pháp ưa thích - Tôi muốn có một vài dòng mã tùy chỉnh hơn hỗ trợ toàn bộ thư viện của bên thứ ba cho một loại trường đơn lẻ. Tony Abou-Assaleh có một giải pháp tuyệt vời, nhưng sẽ không hoạt động cho các phiên bản mới hơn của Django.

này được xác minh để làm việc với 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 
Các vấn đề liên quan