2016-12-22 1 views
0

Я ударил блокпост, который я потратил несколько часов, пытаясь преодолеть, и я был бы признателен за некоторые рекомендации.Установка пользователя модели текущему пользователю при использовании inlineformset_factory в Django

У меня есть две модели: списки и адреса, со следующей структурой:

class Listings(models.Model): 
    created_date = models.DateTimeField(auto_now_add=True) 
    pub_date = models.DateTimeField(auto_now_add=True) 
    address = models.ForeignKey(Addresses) 
    user = models.ForeignKey(User, on_delete=models.CASCADE) 
    is_active = models.BooleanField(default=1) 

class Addresses(models.Model): 
    address1 = models.CharField(max_length=100) 
    address2 = models.CharField(max_length=100) 
    address3 = models.CharField(max_length=100) 
    address4 = models.CharField(max_length=100) 
    postcode = models.CharField(max_length=8) 

У меня также есть эти:

class AddressForm(ModelForm): 
    class Meta: 
     model = Addresses 
     fields = ['address1', 'address2', 'address3', 'address4', 'postcode'] 

class ListingForm(ModelForm): 
    class Meta: 
     model = Listings 
     fields = ['user'] 

Я пытаюсь создать форму, которая будет добавить новый но единственная информация, которую нужно ввести, - это поля в модели «Адреса». Когда форма отправлена, мне нужен новый объект «Объекты» и новый объект «Адреса», который должен быть создан, но объект «Объекты» должен иметь внешний ключ «user», равный идентификатору текущего пользователя в системе.

Это мнение:

@login_required(login_url='share:login_view',   redirect_field_name='share:addlisting') 
def addlisting(request): 

    ListingInlineFormSet = inlineformset_factory(Addresses, Listings, form=ListingForm, can_delete=False, extra=1) 

    if request.method == 'POST': 

     address_form = AddressForm(request.POST) 
     if address_form.is_valid(): 
      new_address = address_form.save() 
      listing_formset = ListingInlineFormSet(request.POST, request.FILES, instance=new_address) 

      if listing_formset.is_valid(): 
       listing_formset.save() 
       return HttpResponseRedirect(reverse('/listing_added/')) 

    else: 
     address_form = AddressForm() 
     listing_formset = ListingInlineFormSet() 

    return render(request, 'share/addlisting.html', { 
     "address_form": address_form, 
     "listing_formset": listing_formset, 
    }) 

В своем нынешнем состоянии, я получаю форму, содержащую все поля адреса, плюс поле пользователя раскрывающегося. Когда форма отправляется, она создает новый список с двумя внешними ключами: один для выбранного пользователя, а другой для нового только что созданного адреса. Этот конечный результат - это то, что я хочу. ОДНАКО, я не хочу, чтобы в форме было раскрывающееся поле пользователя - мне нужно, чтобы пользователь был настроен на текущего пользователя. Я попытался использовать «exclude = ['user»] в классе ListingForm вместо «fields = [' user»] », но это привело к созданию нового адреса без создания списка, чтобы перейти с ним. Так что все, что у меня есть, это новый адрес, и нет листинга.

Что я делаю неправильно? Я был бы так благодарен за решение этого, так как я очень долго стучал головой о стену!

+0

Я должен отметить, что причины в том числе ListForm (а не только с AddressForm) заключается в том, что я планирую включить другие поля в форму в свое время (которые будут частью объекта «Листы»). Я просто хотел сначала создать структуру формы. У меня есть причины для того, чтобы сохранить адрес отдельно от листинга, следовательно, не помещать адрес в объект листинга. – Kate

ответ

1

В этом случае я бы не использовал набор форм вообще. Если вам нужно собрать информацию о пользователе для создания нового списка, используйте один ListingForm и AddressForm, сохраните новый адрес, а затем сохраните ListingForm с помощью commit=False, назначьте ему имя пользователя и адрес, а затем сохраните экземпляр.

@login_required(login_url='share:login_view', redirect_field_name='share:addlisting') 
def addlisting(request): 
    if request.method == 'POST': 
     address_form = AddressForm(request.POST, prefix="address") 
     listing_form = ListingForm(request.POST, prefix="listing") 
     if address_form.is_valid() and listing_form.is_valid(): 
      new_address = address_form.save() 
      new_listing = listing_form.save(commit=False) 
      new_listing.address = new_address 
      new_listing.user = request.user 
      new_listing.save() 
      return HttpResponseRedirect(reverse('/listing_added/')) 
    else: 
     address_form = AddressForm(prefix="address") 
     listing_form = ListingForm(prefix="listing") 
    return render(request, 'share/addlisting.html', { 
     "address_form": address_form, 
     "listing_form": listing_form 
    }) 

Если вы когда-нибудь много-ко-многим на Listings вам нужно явно сохранять те после сохранения экземпляра, как описано здесь: https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#the-save-method

+0

Ах, я должен был упомянуть, что я планирую добавить больше полей в форму для листинга и что у меня есть причины для того, чтобы сохранить адреса в отдельной таблице ... – Kate

+0

В этом случае вы хотите опустить ' user' из формы листинга и укажите только значения, которые вы собираетесь собирать у пользователя. Затем используйте 'listing_form.save (commit = False)' для создания нового списка в памяти, установите его атрибуты пользователя и адреса ('new_listing.address = new_address; new_listing.user = request.user') и только затем сохраните новый пример. Ничто в вышеизложенном не изменяет ли адреса в отдельной таблице. –

+0

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

Смежные вопросы