Как работать с несохраненными отношениями «многие ко многим» в Django? - PullRequest
5 голосов
/ 06 февраля 2009

У меня есть пара моделей в Django, которые связаны многие ко многим. Я хочу создать экземпляры этих моделей в памяти , представить их пользователю (через вызовы пользовательских методов внутри шаблонов представления) и, если пользователь удовлетворен, сохранить их в базе данных.

Однако, если я пытаюсь что-либо сделать с экземплярами модели (например, вызовом методов рендеринга), я получаю сообщение об ошибке, в котором говорится, что мне нужно сначала сохранить экземпляры. В документации сказано, что это связано с тем, что модели связаны между собой.

Как мне представить объекты пользователю и позволить ему / ей сохранять или удалять их, не загромождая мою базу данных?

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

Thx!

Ответы [ 3 ]

6 голосов
/ 06 февраля 2009

Я бы добавил поле, которое указывает, являются ли объекты «черновыми» или «живыми». Таким образом они сохраняются в запросах, сеансах и т. Д., И django перестает жаловаться.

Затем вы можете фильтровать ваши объекты, чтобы показывать «живые» объекты только в открытых представлениях и показывать только «черновые» объекты пользователю, который их создал. Это также можно расширить, чтобы разрешить «архивные» объекты (или любое другое состояние, которое имеет смысл).

4 голосов
/ 06 февраля 2009

Я думаю, что использование форм django может быть ответом, как указано в этой документации (поиск m2m ...).

Отредактировано, чтобы добавить объяснение другим людям, у которых может быть такая же проблема:

скажем, у вас есть такая модель:

from django.db import models
from django.forms import ModelForm

class Foo(models.Model):
    name = models.CharField(max_length = 30)

class Bar(models.Model):
      foos = models.ManyToManyField(Foo)

  def __unicode__(self):
      return " ".join([x.name for x in foos])

тогда вы не можете вызвать unicode () для несохраненного объекта Bar. Если вы хотите распечатать вещи до того, как они будут сохранены, вы должны сделать это:

class BarForm(ModelForm):
    class Meta:
        model = Bar

def example():      
    f1 = Foo(name = 'sue')
    f1.save()
    f2 = foo(name = 'wendy')
    f2.save()
    bf = BarForm({'foos' : [f1.id, f2.id]})
    b = bf.save(commit = false)
    # unfortunately, unicode(b) doesn't work before it is saved properly,
    # so we need to do it this way: 
    if(not bf.is_valid()):
        print bf.errors
    else:
        for (key, value) in bf.cleaned_data.items():
            print key + " => " + str(value)

Таким образом, в этом случае вам необходимо сохранить объекты Foo (которые вы можете проверить перед сохранением их, используя их собственную форму), и перед сохранением моделей со многими или многими ключами вы также можете проверить их. Все без необходимости сохранять данные слишком рано и портить базу данных или иметь дело с транзакциями ...

0 голосов
/ 23 сентября 2017

Очень поздний ответ, но команда трясогузки сделала отдельное расширение Django под названием django-modelcluster . Это то, что обеспечивает предварительный просмотр проекта CMS.

Это позволяет вам сделать что-то вроде этого (из их README):

from modelcluster.models import ClusterableModel
from modelcluster.fields import ParentalKey

class Band(ClusterableModel):
    name = models.CharField(max_length=255)

class BandMember(models.Model):
    band = ParentalKey('Band', related_name='members')
    name = models.CharField(max_length=255)

Тогда модели можно использовать так:

beatles = Band(name='The Beatles')
beatles.members = [
    BandMember(name='John Lennon'),
    BandMember(name='Paul McCartney'),
]

Здесь ParentalKey является заменой для ForeignKey Джанго. Точно так же у них есть ParentalManyToManyField, чтобы заменить ManyToManyField Джанго *. 1015 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...