CreateView 创建两个模型对象

CreateView creating two model objects

我创建了一个 Form,其中用户设置了一个 Alarm 对象。 Alarm 对象按预期保存到数据库中。但是,问题是:另一个对象,只包含Form中完成的信息,也保存到数据库中。

据我了解,form_valid() for CreateView 保存了表格。我已经尝试了 中建议的两种解决方案,但没有成功。我怀疑问题是由 return super().form_valid(form)Alarm.objects.create() in create_alarm_object().

引起的

Views.py

class AlarmCreateView(LoginRequiredMixin, CreateView):
    """ CreateView for User to create the Alarm object """
    model = Alarm
    form_class = SetAlarmForm
    template_name = 'weather_alarm/set_alarm.html'
    login_url = "/login/"

    def form_valid(self, form):
        self.create_alarm_object(request, form)
        return super().form_valid(form)

    def get_success_url(self, **kwargs):
        return reverse("weather_alarm:active-alarm", kwargs={'pk':self.object.pk})

    def create_alarm_object(self, request, form):
        """ Function to get User's location from IP and create Alarm object """
        ...
        alarm_object = Alarm.objects.create(
            alarm_id=uuid.uuid4(),
            user=self.request.user,
            timezone=user_timezone,
            city=location.raw['address']['city'],
            country=location.raw['address']['country'],
            time=form.cleaned_data['time'].astimezone(pytz.timezone(user_timezone)),
            temp_conditional=form.cleaned_data['temp_conditional'],
            surf_conditional=form.cleaned_data['surf_conditional'],
            temp_max=form.cleaned_data['temp_max'],
            temp_min=form.cleaned_data['temp_min'],
            surf_max=form.cleaned_data['surf_max'],
            surf_min=form.cleaned_data['surf_min'],
        )
        alarm_object.save()

你调试对了。 super 调用 form_valid 和方法 create_alarm_object 正在创建两个对象。

如您在 form_valid method implementation 中所见,它使用 success_url 保存表单和 returns 一个 HttpResponseRedirect 对象。

或者,不要覆盖 form_valid 方法,或者使用以下代码。

解决方法:

def form_valid(self, form):
    self.create_alarm_object(self.request, form)
    return HttpResponseRedirect(self.get_success_url())

编辑:

更新 create_alarm_object 方法以设置 self.object 并删除多余的 save 调用。

def create_alarm_object(self, request, form):
    self.object = Alarm.objects.create(...)
    # no `save` call needed, `create` already creates and returns the saved object.