2

このケースに非常によく似た 2 つのモデルがあります。

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'

クラスベースのビューで関連オブジェクトを保存する正しい方法は何ですか?

アップデート

イベントに割り当てられている既存の場所の更新について尋ねていることを付け加える必要があります。新しいイベントの場所の追加は、 Rohanが提案したEventCreate(CreateView)とおりに行われます。

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())
4

1 に答える 1

3

あなたのsave方法event.locationでは になりますNonelocation インスタンスを作成して保存する必要があります。

更新: 既存のオブジェクトを保存する場合:

Generic views - Modelsを読んだ後、あなたの実装がUpdateView進むべき道であるかどうかはわかりません

ビューを次のように変更することをお勧めします。

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
于 2012-09-12T05:39:50.457 に答える