【问题标题】:CreateView creating two model objectsCreateView 创建两个模型对象
【发布时间】:2018-08-10 23:27:46
【问题描述】:

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

据我了解,form_valid() for CreateView 保存表单。我尝试了another query 中建议的两种解决方案,但均未成功。我怀疑问题是由return super().form_valid(form)create_alarm_object() 中的Alarm.objects.create() 引起的。

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

【问题讨论】:

  • 您可以避免将request 参数传递给create_alarm_object 方法。

标签: python django django-views create-view


【解决方案1】:

您已正确调试它。 super 调用 form_valid 和方法 create_alarm_object 正在创建两个对象。

正如您在form_valid method implementation 中看到的,它保存表单并使用success_url 返回一个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.

【讨论】:

  • 我尝试了建议的后一种解决方案并收到以下错误:AttributeError: 'NoneType' object has no attribute 'pk'。请注意,Primary_Key=True 对应于 alarm_id。我需要在get_success_url() 中引用alarm_id 吗?但是,我检查了数据库,Alarm 对象现在正确保存了一个对象!
  • 抱歉。 return reverse("weather_alarm:active-alarm", kwargs={'pk':self.object.pk})
  • 这是一个不同的问题。尽管您可以通过将create_alarm_object 方法中的self.object 设置为您创建的方法来轻松解决它。
猜你喜欢
  • 1970-01-01
  • 2020-05-03
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
  • 1970-01-01
  • 2013-04-12
  • 2012-10-29
相关资源
最近更新 更多