如何在Django数据库模型的字段中存储字典

时间:2021-09-26 13:26:26

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?

我为“bill_products =”写了什么,所以它保存了一些随机产品,从我的产品型号到这个账单?

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!

如果还有什么我应该添加只是留下评论。谢谢!

7 个解决方案

#1


5  

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

可能最干净的事情是创建另一个“产品”表并具有多对多关系。 (见这里:https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationships。在文档中,他们使用了一个有很多浇头的比萨饼的例子。)

The other option would be to serialize your bill_products. In that case, you'd do something like:

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

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

这将在for循环之外(尽管在上面的示例中,rand_products只是一个值,因此您需要修复它)。

#2


18  

I just discovered the django-jsonfield package, which

我刚刚发现了django-jsonfield包,其中

is a reusable Django field that allows you to store validated JSON in your model.

是一个可重用的Django字段,允许您在模型中存储经过验证的JSON。

Looks like a viable option to achieve what you want.

看起来是实现您想要的可行选择。

#3


9  

One convenient way to store a JSON representation in a model is to use a custom field type:

在模型中存储JSON表示的一种便捷方法是使用自定义字段类型:

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.

我从utils.fields导入JSONField中保存了这个utils / fields.py和我的模型。 django-annoying app中还有很多好东西,这是这个代码片段的来源。

#4


6  

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.

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

This is verified to work with Django 1.10.4

经验证可以与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


3  

You can use serialization/deserialization from pickle module:

您可以使用pickle模块中的序列化/反序列化:

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

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

#6


3  

If postgres is your backend, consider the hstore field which has native support from django

如果postgres是你的后端,请考虑具有django本机支持的hstore字段

#7


1  

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.

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

#1


5  

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

可能最干净的事情是创建另一个“产品”表并具有多对多关系。 (见这里:https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationships。在文档中,他们使用了一个有很多浇头的比萨饼的例子。)

The other option would be to serialize your bill_products. In that case, you'd do something like:

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

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

这将在for循环之外(尽管在上面的示例中,rand_products只是一个值,因此您需要修复它)。

#2


18  

I just discovered the django-jsonfield package, which

我刚刚发现了django-jsonfield包,其中

is a reusable Django field that allows you to store validated JSON in your model.

是一个可重用的Django字段,允许您在模型中存储经过验证的JSON。

Looks like a viable option to achieve what you want.

看起来是实现您想要的可行选择。

#3


9  

One convenient way to store a JSON representation in a model is to use a custom field type:

在模型中存储JSON表示的一种便捷方法是使用自定义字段类型:

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.

我从utils.fields导入JSONField中保存了这个utils / fields.py和我的模型。 django-annoying app中还有很多好东西,这是这个代码片段的来源。

#4


6  

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.

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

This is verified to work with Django 1.10.4

经验证可以与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


3  

You can use serialization/deserialization from pickle module:

您可以使用pickle模块中的序列化/反序列化:

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

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

#6


3  

If postgres is your backend, consider the hstore field which has native support from django

如果postgres是你的后端,请考虑具有django本机支持的hstore字段

#7


1  

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.

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