Как хранить словарь в поле модели базы данных Django

19

Мне нужно сохранить словарь в поле модели. Как это сделать?

Например, у меня есть этот код:

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

Если есть что-то еще, я должен добавить только оставить комментарий. Спасибо!

    
задан Radu Gheorghiu 13.03.2012 в 15:49
источник
  • Какая черта - это «модель базы данных python»? Используете ли вы конкретный ORM или фреймворк? это выглядит немного «джанго-иш» –  SingleNegationElimination 13.03.2012 в 15:58
  • Да, это Django. Я только начинаю работать с ним, поэтому я могу смешивать «Python» с «Django». Я изменю название. –  Radu Gheorghiu 13.03.2012 в 16:02

7 ответов

6

Вероятно, самой чистой задачей было бы создать другую таблицу «Продукты» и иметь отношения «многие ко многим». (См. Здесь: Ссылка . В документах, которые они используют пример пиццы с большим количеством начинок.)

Другой вариант - это сериализовать ваши bill_products. В этом случае вы бы сделали что-то вроде:

bill_products = json.dumps([rand_products])

Это будет за пределами цикла for (хотя в приведенном выше примере rand_products - это только одно значение, поэтому вам нужно это исправить).

    
ответ дан gdw2 13.03.2012 в 16:12
источник
  • Если бы вы могли привести пример, было бы очень приятно. Боюсь, я не понял, как именно перевести отношения «ко многим ко многим» в мой код. Я нахожусь на правильном пути идеи с сохранением массива с именами продуктов в этом поле? Или я мог бы сделать это в более простом подходе? –  Radu Gheorghiu 14.03.2012 в 18:23
  • @reos. Вы на правильном пути. Вот полный пример: djangoproject.com/documentation/0_91/models/many_to_many –  gdw2 14.03.2012 в 19:26
17

Я только что обнаружил пакет django-jsonfield , который

  

- это многократно используемое поле Django, которое позволяет хранить проверенную JSON в вашей модели.

Похож на реальный вариант для достижения желаемого.

    
ответ дан ramiro 08.05.2013 в 11:54
источник
  • Спасибо за обновление. Приятно знать, даже если эта проблема была исправлена ​​давным-давно. –  Radu Gheorghiu 08.05.2013 в 14:09
8

Одним удобным способом хранения 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)

Я сохранил этот utils / fields.py и в моей модели from utils.fields import JSONField . В django-annoying приложении есть много других полезных свойств, из которых этот фрагмент пришел.

    
ответ дан Tony Abou-Assaleh 13.03.2012 в 21:40
источник
6

Использование настраиваемого типа поля - это мое предпочтительное решение. Я бы предпочел иметь несколько строк пользовательского кода, чем поддерживать всю стороннюю библиотеку для одного типа поля. У Тони Абу-Ассале есть отличное решение, но он не будет работать для более новых версий 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
    
ответ дан Rico 24.01.2017 в 22:07
источник
3

Вы можете использовать сериализацию / десериализацию из модуля рассола:

Ссылка

    
ответ дан Alejandro Veintimilla 23.12.2013 в 06:41
источник
3

Если postgres - это ваш бэкэнд, рассмотрите поле hstore, которое имеет встроенную поддержку от django

    
ответ дан wjin 01.01.2015 в 15:25
источник
  • Благодарим вас за ответ, но на это уже давно ответили и решили. И бэкэнд для этого был SQLLite –  Radu Gheorghiu 01.01.2015 в 15:27
1

Я думаю, что я создам поле как models.CharField (), а затем закодирует словарь как строку JSON и сохранит эту строку в базе данных. Затем вы можете декодировать строку JSON обратно в словарь, когда вы его прочитали.

    
ответ дан brian buck 13.03.2012 в 16:10
источник
  • Я добавил описание модели Билла. –  Radu Gheorghiu 13.03.2012 в 16:14