2013-10-04 4 views
1

이것은 위도/경도 FloatFields로 구성된 PointField를 구성하는 방법을 알아 내려고 시도한 this question의 연속입니다. 나는 다음과 같이 시몬의 조언 @ 찍은 내 모델을 재구성 한 :Django : 양식에서 외래 키 저장

class Point(models.Model): 
    lat = models.FloatField() 
    lon = models.FloatField() 

class Thing(models.Model): 
    point = models.ForeignKey(Point) 

내 양식이 구글 맵 '경도와 위도의 값에 해당하는 두 개의 필드 좌표했습니다

class StepThreeForm(forms.Form): 
    lat = forms.FloatField() 
    lon = forms.FloatField() 
    ... 

을하지만,이 수행 명백한 이유 때문에 작동하지 않지만이를 수정하는 방법을 모르겠습니다. 명확히하기 위해 외래 키 값인 latlon에 해당하는 두 개의 양식 필드를 갖기 위해 노력하고 있습니다.


url(r'^mapform/$', login_required(MyWizard.as_view([StepOneForm, StepTwoForm, StepThreeForm])), name='create'), 

class MyWizard(SessionWizardView): ## this view also serves to edit existing objects and provide their instances 
    def done(self, form_list, **kwargs): 
     id = form_list[0].cleaned_data['id'] 
     try: 
      thing = Thing.objects.get(pk=id) 
      instance = thing 
     except: 
      thing = None 
      instance = None 
     if thing and thing.user != self.request.user: 
      raise HttpResponseForbidden() 
     if not thing: 
      instance = Thing() 
      for form in form_list: 
       for field, value in form.cleaned_data.iteritems(): 
        setattr(instance, field, value) 
      instance.user = self.request.user 
      instance.save() 
     return render_to_response('wizard-done.html', { 
       'form_data': [form.cleaned_data for form in form_list],}) 

내가 일체의 조언을 주셔서 감사합니다 도움 : 여기에 (나는 FormWizard 및 forms.Form을 사용하고 있습니다) 보충 정보입니다!


EDIT : Yuji Tomita의 입력을 기반으로 업데이트. 그것의 대부분은 (감사합니다!) 많은 감각을 만들었지 만 ValueError를 초래하는 이유는 확실하지 않습니다.

class MyWizard(SessionWizardView): 
    .... 
      for form in form_list: 
       form.save(instance) 
    ... 

class StepOneForm(forms.Form): 
    ... 
    def save(self, thing): 
     for field, value in self.cleaned_data.items(): 
      setattr(thing, field, value) 

class StepTwoForm(forms.Form): 
    ... 
    def save(self, thing): 
     for field, value in self.cleaned_data.items(): 
      setattr(thing, field, value) 

그때 그 값에서 소수점 필드를 구성, 내 형태의 구글 맵을 사용하고, 선택한 입력에서 위도와 경도를 복용하고 있기 때문에, 나는 위도와 경도 등의 양식 필드를 유지해야한다고 생각합니다 :

class StepThreeForm(forms.Form): 
    lat = forms.FloatField() 
    lon = forms.FloatField() 

    def save(self, thing): 
     thing.point = Point.objects.get_or_create(lat=self.cleaned_data.get('lat'), lon=self.cleaned_data.get('lon')) 

이것은 내가 방법을 알고있는 양식의 각에 save 방법을 구축하는 것이 좋습니다 거라고 ValueError: Cannot assign "(<Point: Point object>, False)": "Thing.point" must be a "Point" instance.

Traceback: 
File "/lib/python2.7/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/lib/python2.7/django/contrib/auth/decorators.py" in _wrapped_view 
    20.     return view_func(request, *args, **kwargs) 
File "/lib/python2.7/django/views/generic/base.py" in view 
    48.    return self.dispatch(request, *args, **kwargs) 
File "/lib/python2.7/django/contrib/formtools/wizard/views.py" in dispatch 
    223.   response = super(WizardView, self).dispatch(request, *args, **kwargs) 
File "/lib/python2.7/django/views/generic/base.py" in dispatch 
    69.   return handler(request, *args, **kwargs) 
File "/lib/python2.7/django/contrib/formtools/wizard/views.py" in post 
    286.     return self.render_done(form, **kwargs) 
File "/lib/python2.7/django/contrib/formtools/wizard/views.py" in render_done 
    328.   done_response = self.done(final_form_list, **kwargs) 
File "/myproject/myapp/forms.py" in done 
    93.  form.save(instance) 
File "/myproject/myapp/forms.py" in save 
    67.   thing.point = Thing.objects.get_or_create(lat=self.cleaned_data.get('lat'), lon=self.cleaned_data.get('lon')) 
File "/lib/python2.7/django/db/models/fields/related.py" in __set__ 
    366.         self.field.name, self.field.rel.to._meta.object_name)) 
+0

당신의 [원래의 질문에] 편집하세요 (http://stackoverflow.com/questions/19167076/django-filtering-queryset-from-two-model-fields) 여러 스레드를 통해 확산하는 대신. –

+0

제 질문은 질문이 원본보다 다른 것을 묻는다면 새로운 질문을 시작해야한다는 것입니다. 이전 질문은 두 개의 분리 된 모델 필드를 기반으로 '필터링'하는 방법에 관한 것이 었습니다. 그것은 대답했다.이 주제는 두 개의 모델 필드의 조합을 기반으로하는 필터링과는 완전히 다른 연습 인 'ForeignKey' 필드를 양식에서 저장하는 방법을 묻기 때문에 다릅니다. 내가 잘못했다면 나는 사회자에게 분명히 알릴 수있을 것이다. 감사! –

+0

@NickB, 여기 괜찮습니다. 우리는 모두 게시물을 읽을 때 갑작스런 가정을합니다. 그것에 대해 시민이되어 주셔서 감사합니다! –

답변

3

산출 데이터베이스에 자신을 저장합니다. "폼이 form.save()를 통해 액션을 수행한다는 일반적인 패턴을 따르므로이를 직관적으로 따라야합니다.

결말은 이제 담요가 있습니다 : "모든 양식의 모든 입력란에 대해 해당 입력란의 속성을 설정하십시오".

실제로 양식마다 저장 동작이 있으므로 각 양식에 해당 필드에 적합한 방식으로 데이터를 저장할 수 있도록 각 양식에 인스턴스를 전달해야한다는 것이 맞다고 생각합니다.

class Form1(...): 
    def save(self, thing): 
     for field, value in self.cleaned_data.items(): 
      setattr(thing, field, value) 

class Form2(...): 
    def save(self, thing): 
     thing.point = Point.objects.get_or_create(lat=self.cleaned_data.get('lat'), long=...) 
     # note, you may not want get_or_create if you don't want to share points. 

로보기는 될 것입니다 :

for form in form_list: 
    form.save(instance) 

그냥 생각.

당신이 그것에 대해와 다른 형태의 자동화와 같은 더 건조 할 경우, 이미 정의 된 저장 방법이 기본 양식을 구축 할 것 :

class BaseSaveBehaviorForm(forms.Form): 
    def save(self, thing): 
     for field, value in self.cleaned_data.items(): 
      setattr(thing, field, value) 

class NormalBehaviorForm(BaseSaveBehaviorForm): 
    # your forms as usual 


class SpecialSaveBehaviorForm(forms.Form): 
    def save(self, instance): 
     # do something unusual 
+0

와우 덕분에 많은 도움이되었고 양식에서 무슨 일이 벌어지고 있는지 더 자세히 설명 할 수있었습니다. 고맙습니다! 내 시도가'ValueError' 결과로 잘못 구현 한 것 같습니다. 잠시 시간을내어 내가 잘못한 일에 대한 의견을 듣는 것은 멋지 겠지만, 너무 바빠서 나는 또한 이해합니다. 다시 한 번 감사드립니다! –

+0

@NickB, 문제 없습니다. 오류는 내 잘못입니다. get_or_create는 인스턴스와 생성 된 플래그 또는 생성되지 않은 플래그를 반환합니다. 'thing.point = Point.objects.create (lat = lat, long = long)'또는'thing.point = ... get_or_create() [0]' –

+0

환자 지원에 감사드립니다. 나는 당신의 설명에서 많은 것을 배웠고 FormWizard에 객체를 적절히 저장할 수있게되었습니다! 다시 한 번 감사드립니다! –