2012-09-12 49 views
2

我有兩個機型非常相似,this caseDjango的:無法保存相關模型CBV

class Location(models.Model): 
    city = models.CharField(max_length=20) 
    address = models.CharField(max_length=30) 

class Event(models.Model): 
    location = models.ForeignKey(Location)  
    date = models.DateField() 
    user = models.ForeignKey(User) 

我試圖在形式保存這些對象:

class EventForm(forms.ModelForm): 
    city = forms.CharField(label=_('City'), max_length=30) 
    address = forms.CharField(label=_('Street'), max_length=30, required=False) 

    class Meta: 
     model = Event 

    def __init__(self, *args, **kwargs) 
     super(EventForm, self).__init__(*args, **kwargs) 
     try: 
      self.fields['city'].initial = self.instance.location.city 
      self.fields['address'].initial = self.instance.location.street 
     except AttributeError: 
      pass 

    def save(self, commit=True): 
     event = super(EventForm, self).save(commit=False) 
     location = event.location 
     location.city = self.cleaned_data['city'] 
     location.address = self.cleaned_data['address'] 
     location.save() 
     return event 

這將引發錯誤'NoneType' object has no attribute 'city'

我也嘗試在CBV中保存位置:

class EventEdit(UpdateView): 
    model = Event 

    def form_valid(self, form): 
     event = form.save(commit=False) 
     location = event.location 
     location.city = self.cleaned_data['city'] 
     location.address = self.cleaned_data['address'] 
     location.save() 
     event.save() 
     return HttpResponseRedirect(self.get_success_url()) 

同樣,同樣的錯誤'NoneType' object has no attribute 'city'

在基於類的視圖中保存相關對象的正確方法是什麼?

更新

我要補充一點,我想諮詢一下更新現有的位置分配給事件。添加新事件位置在EventCreate(CreateView)中完成,與完全相同,建議使用Rohan

class EventCreate(CreateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     location = Location() 
     location.address = self.request.POST['address'] 
     location.city = self.request.POST['city'] 
     location.save() 
     self.object.location = location 
     self.object.save() 
     return HttpResponseRedirect(self.get_success_url()) 

回答

3

在你save方法event.locationNone。您需要創建location 實例,然後將其保存。

更新:爲了節約現有對象:

我不知道你的UpdateView實施辦法讀Generic views - Models

去後我會建議改變的觀點爲:

class EventEdit(UpdateView): 
    model = Event 

    def form_valid(self, form): 
     #instance trying to update 
     event = form.instance 
     location = event.location 
     if location == None: 
      location = Location() 
     location.city = self.cleaned_data['city'] 
     location.address = self.cleaned_data['address'] 
     location.save() 
     event.location = location 
     #event.save() instead of this do 
     super(EventEdit, self).form_valid(form) 
     return HttpResponseRedirect(self.get_success_url()) 

舊解決方案:

我會更改保存方法爲

def save(self, commit=True): 
    event = super(EventForm, self).save(commit=False) 
    location = Location() 
    location.city = self.cleaned_data['city'] 
    location.address = self.cleaned_data['address'] 
    location.save() 
    event.location = location 
    event.save() 
    return event 
+0

感謝您的回覆!這正是我在'EventCreate(CreateView).form_valid()'中所做的,並且它工作正常。但我需要獲取並更新已分配給事件的現有位置。 –

+0

@VladT。檢查更新的答案 – Rohan

+0

嘗試更新的解決方案,現在它會在每次更新時創建新的「位置」對象。似乎無法從'event.location'和我的版本中獲取位置(始終爲None)。 –