2014-01-27 3 views
1

Workshop 장고 앱이 있습니다. 각 Workshop은 관련 WorkshopAttendee 모델 (아래 단순화 됨)을 통해 여러 참석자를 가질 수 있습니다. 나는 클래스를 기반으로보기에 장고의 ModelForm를 사용하고, 그리고 forms.py에서 나는 crispy-forms을 사용하고 있습니다 :Django ModelForms : FK 관련 필드를 시드 형식으로 시드

models.py (관련 부분)

class Workshop(models.Model): 
    title = models.CharField(max_length=100) 
    information = models.TextField() 
    location = models.TextField() 

class WorkshopAttendee(models.Model): 
    workshop = models.ForeignKey(Workshop) 
    first_name = models.CharField(max_length=100) 
    last_name = models.CharField(max_length=100) 

views.py (관련 부분)

from django.views.generic.edit import FormView 
from workshop.forms import WorkshopAttendeeForm 

class WorkshopAttendeeFormView(FormView): 

    def form_valid(self, form): 
     # Clean the data 
     form_data = form.cleaned_data 
     form.save(commit=False) 
     return super(WorkshopAttendeeFormView, self).form_valid(form) 

forms.py

from django.forms import ModelForm 
from workshop.models import WorkshopAttendee 
from crispy_forms.helper import FormHelper 
from crispy_forms.layout import Layout, HTML, Field, \ 
    Fieldset, Button, Hidden, Submit, Reset 
from crispy_forms.bootstrap import FormActions 

# Create the form class 
class WorkshopAttendeeForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
     # Crispy form Layouts, Fieldsets, etc 
     super(WorkshopAttendeeForm, self).__init__(*args, **kwargs) 

    class Meta: 
     model = WorkshopAttendee 

urls.py (관련 부분) 나는 을 workshop_id와 양식을 시드 할 수있는 방법

urlpatterns = patterns('', 
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[\w\-.]+)/(?P<action>[\w\-.]+)/$', 
     WorkshopAttendeeFormView.as_view(
      form_class=WorkshopAttendeeForm, 
      success_url="success/", 
      template_name='workshop/workshop_registration.html', 
     ), name='workshop-attendee-register' 
    ), 
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[\w\-.]+)/$', 
     WorkshopDetailView.as_view(
      context_object_name='workshop_detail', 
      queryset=Workshop.objects.select_related(), 
      template_name='workshop/workshop_detail.html', 
     ), name='workshop-detail' 
    ), 
) 

내 질문은, (즉, FK 관계) 숨겨진 양식 필드에? 양식이 아직 제출되지 않았으므로 분명히 FK 관계가 없습니다. 하지만 URL에 나는 kwargWorkshop슬러그 있습니다. workshop_id을 워크샵 단위로 Hidden() 파삭 파삭 한 양식 필드로 하드 ​​코드 할 수 있지만 이는 전적으로 unDRY입니다. 어떤 아이디어? 나는 모델에서 select_related() 또는 prefetch_related() 메서드를 urls.py에 사용할 수 있다고 생각하지 않습니다. 어쨌든 두 모델을 어떻게 든 폼 뷰로 가져와야합니까?

나는 이것이 가장자리의 시나리오 인 것 같은 기분이 아니며, 다른 누군가가 비슷한 앱 워크 플로우를 가졌다 고 확신합니다.

미리 감사드립니다.

UPDATE

은 추가 연구 후에 내가 Django Formsets를 사용하여이 작업을 수행 할 수 있다는 것을 나타납니다. 정확히 어떻게 ..... 아직 힌트를 환영합니다.

+1

당신은 슬러그를 가지고 있죠? 당신이 아무것도 저장하기 전에 PK를 얻기 위해 그것을 당신의 관점에서 사용하지 않는 이유는 무엇입니까? 왜 양식으로 전달해야합니까? – Thomas

+0

맞아. 내 견해에서 정확히 어디에 사용하겠습니까? 양식에 PK를 전달해야하므로이 WorkshopAttendee가 적용되는 '워크샵'을 알 수 있습니다. 말이 돼? – tatlar

+0

'WorkshopAttendeeFormView'에'get()'메소드를 생성합니까? 그것은 그것을 할 곳과 같습니다 ... – tatlar

답변

0

나는 이것을 지나치게 복잡하게했다.

내가 할 필요가 모든이에 대한 장고의 GCBV FormView에 대한 form_valid 방법을 수정했다 :

워크샵/views.py 기본적으로 제출에 양식을 저장하지 않습니다

from django.views.generic.edit import FormView 
from workshop.models import Workshop, WorkshopAttendee 
from workshop.forms import WorkshopAttendeeForm 
from django.http import HttpResponseRedirect 

class WorkshopAttendeeFormView(FormView): 

    def form_valid(self, form): 

     self.object = form.save(commit=False) 
     self.object.workshop = Workshop.objects.filter(slug=self.kwargs['slug'])[0] 
     self.object.save() 
     return HttpResponseRedirect(self.get_success_url()) 

하지만, 대신 Workshop (고유 한 Workshop 슬러그 필드에 기반), , 저장하여 객체를 저장하려고합니다 (WorkshopAttendee 객체). 업데이트 된 개체 (self.object.save)와 성공 URL에 나를 걷어 찬다.

@ init3에게 도움이되는 정보에 큰 감사를드립니다. 매우 감사.

+0

아, 그게 좋은 해결책입니다. 잘 한 tatlar – Thomas

2

PK를 전달할 필요가 없습니다. 이미 URL에 슬러그를 넣었습니다.

그래서의 말을하자이 당신의 URL입니다 : http://example.com/workshops/awesome-workshop-slug/sign_in/ 귀하의 urls.py 다음과 같아야합니다

url(r'^workshop/(?P<workshop_slug>\w+)/sign_in/$', 
     # ../workshops/awesome-workshop-slug/sign_in/ 
     view = 'workshop_signin', 
     name = 'workshop-signin', 
    ), 

좋아, 당신의 views.py이 할 수있어 : 검증되지 않은

@login_required 
def workshop_signin(request, workshop_slug, template='workshop/sign_in.html'): 
    """Register user to workshop.""" 
    form = WorkshopForm() 
    workshop = Workshop.objects.filter(slug=workshop_slug)[0] 

    if request.method == 'POST': 
     form = WorkshopForm(request.POST, instance=workshop) 
     if form.is_valid(): 
      messages.info(request, 'Yay!') 


    kwargs = { 
     'workshop_form': form, 
    } 
    return render_to_response(template, kwargs, context_instance=RequestContext(request)) 

*를 빠르고 불결한 코드

+0

감사합니다 @ init3,이 날 올바른 방향으로 이동하고있다. 불행히도 나는 당신의 코드를 그대로 사용할 수 없다 - 나는 Django의 Generic CBV를 전체적으로 사용하고있다. 그러나 이것이 바로 [Django source file] (https://github.com/django/django/blob/master /django/views/generic/edit.py) – tatlar

+0

보다 더 나은 것 - 다행히 도울 수있어서 기쁩니다. – Thomas

+1

내 문제 해결과 함께 올바른 방향으로 움직이고 있습니다. 건배. – tatlar