Django: сохранение нескольких моделей одновременно (сложный случай) - PullRequest
1 голос
/ 17 февраля 2011

Ну, на самом деле, это может быть простой случай, но мне сложно разобраться.

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

Я знаю, как решить эту проблему, выполняя дополнительные синхронные или асинхронные запросы, но я бы хотел, чтобы пользователь заполнил три формы и отправил их одним щелчком мыши.

Моя проблема заключается в том, что две другие формы полагаются на внешний ключ пользователя в качестве поля. Я сделал это поле "null = True, blank = True", чтобы я мог проверять и сохранять формы без внешнего ключа, но в конечном итоге я хочу добавить этот ключ в оба экземпляра модели.

Я подумал, что смогу проверить три формы, сохранить пользовательскую форму, а затем использовать набор запросов модели для возврата нового User.id (все в одном представлении). Затем я бы добавил это значение user_id в два других словаря форм (WebsiteForm и Organization_ContactForm).

Это будет работать так:

def register_company(request):
    if request.method=='POST'
       uform=UserCreationForm(request.POST, prefix='user')
       sform=SiteForm(request.POST, prefix='site')
       oform=OrgForm(request.POST, prefix='site')
       if uform.is_valid() and sform.is_valid() and oform.is_valid():
            uform.save()
            user=User.objects.get(email__iexact=uform.cleaned_data['email'])
            uid=unicode(user.id)
       #now I'd add uid back into the SiteForm and Orgform dictionaries and then save both instances              

Проблемы: 1) Не уверен, смогу ли я сохранить форму модели и затем вернуть этот экземпляр модели как набор запросов в одном представлении

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

Кажется, что метод get manager не принимает переменную там. Я предполагаю, что столько, сколько я передал эквивалентную жестко закодированную строку, и это работало

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

Я также думал, что смогу решить эту проблему с помощью сигнала после сохранения.

Просто общее руководство здесь было бы очень полезно. Мне нужна отправная точка.

Ответы [ 2 ]

2 голосов
/ 17 февраля 2011

Это все ModelForm с?

if request.method=='POST'
   uform=UserCreationForm(request.POST, prefix='user')
   sform=SiteForm(request.POST, prefix='site')
   oform=OrgForm(request.POST, prefix='site')
   if uform.is_valid() and sform.is_valid() and oform.is_valid():
        # save returns the object 
        user = uform.save()

        # commit = false doesn't save to DB.
        site = sform.save(commit=False)
        site.user = user
        site.save()

        org = oform.save(commit=False)
        org.user = user
        org.save()

Обновление в отношении комментариев: зачем распространять эту логику сохранения формы на несколько областей и файлов (сигналы, сохранение формы), когда вы можете сделать это в одном месте?

Код более читабелен, и вы даже сохраняете строки кода.Если только он не будет использоваться во всем мире.

0 голосов
/ 17 февраля 2011

Вот как бы я это сделал:

def register_company(request):
    uform=UserCreationForm(request.POST or None, prefix='user')
    sform=SiteForm(request.POST or None, prefix='site')
    oform=OrgForm(request.POST or None, prefix='site')

    if request.POST and all((uform.is_valid(), sform.is_valid(), oform.is_valid()):
        user = uform.save()
        sform.save(user)
        oform.save(user)

    ruturn ...

class UserCreateionForm(ModelForm):
    Meta:
        model = User

class SiteForm(ModelForm):
    Meta:
        model=Site
        exclude=['user', ]

    def save(self, user, commit=True):
        self.instance.user = user
        return super(SiteForm, self).save(commit=commit)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...