2016-12-22 9 views
0

나는 극복하기 위해 몇 시간을 허비했지만 시간이 많이 걸렸습니다. 다음과 같은 구조로, 목록 및 주소 :Django에서 inlineformset_factory를 사용할 때 모델 사용자를 현재 사용자로 설정

나는 두 가지 모델이

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'] 

을 그러나 입력 할 수있는 유일한 정보는 Addresses 모델의 필드입니다. 양식이 제출되면 새 리스팅 객체와 새 Addresses 객체가 생성되어야하지만 Listings 객체에는 현재 로그인 한 사용자의 ID와 동일한 '사용자'외래 키가 있어야합니다.

뷰입니다 : 현재 상태에서

@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, 
    }) 

, 나는 모든 주소 필드, 플러스 드롭 다운 사용자 필드를 포함하는 양식을 얻을. 양식이 제출되면 두 개의 외래 키 (하나는 선택한 사용자 용이고 다른 하나는 방금 작성된 새 주소 용)가있는 새 목록을 작성합니다. 이 최종 결과는 내가 원하는 것입니다. 그러나 양식에 드롭 다운 사용자 입력란을 표시하고 싶지 않습니다. 사용자를 현재 사용자로 설정해야합니다. 나는 "fields = [ 'user']"대신에 ListingForm 클래스에서 "exclude = [ 'user']"를 사용하려고 시도 했었지만,이 경우에는 목록을 만들지 않고 새 주소를 생성 한 결과가있었습니다. 그래서 나는 새로운 주소와 목록이 없다.

내가 뭘 잘못하고 있니? 나는 매우 오랫동안 벽에 머리를 부딪 히고 있었기 때문에 이것에 대한 해결책에 대해 매우 감사 할 것입니다!

+0

을 (단순히 AddressForm을 가지는 것보다) ListingForm을 포함하여 (물론 Listings 객체의 일부가 될 것입니다) 폼에 다른 필드를 포함 할 계획입니다. 먼저 폼 구조를 먼저 얻고 싶습니다. 주소를 목록과 분리하여 주소를 목록 개체에 넣지 않으려는 이유가 있습니다. – Kate

답변

1

이 경우 나는 formset을 전혀 사용하지 않을 것입니다. 새 목록을 만들려면 사용자 정보를 수집해야하며 하나만 ListingFormAddressForm을 사용하고 새 주소를 저장 한 다음 을 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

formset을 사용하여 사용자에게 현재 목록을 표시하고 새 목록을 추가하려는 경우 위의 디자인을 formset으로 적절하게 변환해야합니다. 즉, 양식을 사용자가 명시 적으로 명시 적으로 유지해야합니다. 변경된 인스턴스에서 설정하면 숨겨진 입력 위젯을 사용하는 것보다 다소 제어가됩니다. –