【问题标题】:Model field doesn't get updated on first save模型字段在第一次保存时不会更新
【发布时间】:2019-01-10 12:54:24
【问题描述】:

我有这个 UpdateView 用来更新我的频道:

class ChannelUpdate(UpdateView, ProgramContextMixin):
    model = ChannelCategory
    form_class = ChannelForm
    template_name = 'app/templates/channel/form.html'

    def dispatch(self, request, *args, **kwargs):
        return super(ChannelUpdate, self).dispatch(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('channel_index', args=[self.get_program_id()])

    def get_context_data(self, **kwargs):
        context = super(ChannelUpdate, self).get_context_data(**kwargs)
        context.update({
            'is_new': False,
        })
        return context

    def form_valid(self, form):
        channel = Channel.objects.get(id=self.kwargs['pk'])
        channel_codes = ChannelCodes.objects.filter(channel_id=channel.pk)

        if 'is_channel_enabled' in form.changed_data:
            for channel_code in channel_codes:
                channel_code.is_active = channel.is_channel_enabled
                channel_code.save()
        return super(ChannelUpdate, self).form_valid(form)

因此,当我编辑频道时,我有一个复选框,它将我的模型字段 is_channel_enabled 的布尔值更改为 True 或 False。如果这样做,我会在 def form_valid 方法中触发我的 if 语句,然后循环遍历我的所有 channel_code 并将它们的 bool 字段 is_active 设置为与我的 Channel 中的 bool 字段 is_channel_enabled 相同的值。

但我现在的问题是:假设我取消选中该框,保存表单后,布尔值仍然是 True,即使我已取消选中该框并且它应该是 False,但如果我随后编辑我的再次通道并选中该框,布尔值更改为False,因此每次我选中该框时,都会发生完全相反的情况:选中框= False,未选中框= True。

但这也只会在我进行更新时发生。如果我创建通道,True 的默认值是正确的,只有当我开始编辑它时,才会保存错误的值。有人知道我的问题在哪里吗?我是不是用错了 form_valid?

感谢您的帮助!

【问题讨论】:

  • 你不应该使用form.cleaned_data,而不是form.changed_data,比如form.cleaned_data['is_channel_enabled']吗?
  • @WillemVanOnsem 我查找了如何检查模型字段中的更改,发现changed_data 是这样做的方法,cleaned_data 也会这样做吗?
  • form 不是模型,它是Form
  • @WillemVanOnsem 好吧,我试了一下,但我收到的是错误argument of type 'bool' is not iterable:/ 我对 Django 很陌生,如果我误解了一些东西,很抱歉
  • 使用if form.cleaned_data['is_channel_enabled']:

标签: python django


【解决方案1】:

您没有更新最新值。 您可以像下面这样更改表单的有效方法

def form_valid(self, form):
    # channel = Channel.objects.get(id=self.kwargs['pk'])
    channel_codes = ChannelCodes.objects.filter(channel_id=self.kwargs['pk'])

    if 'is_channel_enabled' in form.changed_data:
        for channel_code in channel_codes:
            channel_code.is_active = form.cleaned_data.get('is_channel_enabled')
            channel_code.save()
    return super(ChannelUpdate, self).form_valid(form)

它会起作用的。

【讨论】:

  • 这只会返回错误:'list' object has no attribute 'get' at line:channel_code.is_active = form.changed_data.get('is_channel_enabled')
  • @unitas_versus 是的,这是类型问题。 cleaned_data 而不是 changed_data。更新代码请检查。
  • 没有更多错误,但遗憾的是无法正常工作。我记录了我的值并发生以下情况: 1. is channel_enabled(未选中)为 False | 2.channel_code.is_active提交前为True | 3.channel_code.is_active设置新值后还是True | 4.is_channel_enabled勾选复选框后为True
  • 我意识到它在上面所做的这个评论听起来有点令人困惑:制作一个 TL;DR:我的 channel_code.is_active 始终保持 True 无论 channel_enabled 有什么价值
  • 你检查了输入复选框吗?我想如果您选中表单中的复选框,它应该返回 true。
猜你喜欢
  • 1970-01-01
  • 2015-02-18
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
相关资源
最近更新 更多