如何在UpdateView中更改M2M字段?

时间:2013-12-15 21:30:17

标签: python django

Peter DeGlopper解决:

感谢您的帮助它解决了我的问题,我真的很感激。我正撞在桌子上。

  1. 我没有必要更改我的ModelForm。查看我在输入标记中注意到的HTML源代码 checked =“checked”子网正在输出为已检查但未在我的浏览器中显示已检查。这是在CentOS(在虚拟机上)的Firefox 24.2.0中,所以我去了我的Windows 7主机并加载了它运行的Firefox 26.0,并且在IE8中也运行良好。这很奇怪,但它解释了你应该发挥作用的困惑。

  2. 为了保存字段,感谢你,我现在看到我是如何思考它的。我可以更新M2M字段。我更新了下面的TagUpdateView以显示工作代码。


  3. 尝试使用带有M2M字段的UpdateView时遇到2个问题......

    1. 当前“已标记”的子网不会在我的模板中显示为
    2. 如何通过覆盖form_valid来处理更新TagUpdate中的M2M关系?
    3. 非常感谢任何见解。 感谢。

      标记m2m models.py:

      class Tag(models.Model):
          tag = models.CharField(max_length=120)
          group = models.ForeignKey(Group)
          description = models.TextField(max_length=500)
          subnet = models.ManyToManyField(Subnet, null=True, blank=True)
          date_created = models.DateTimeField()
          created_by = models.ForeignKey(User, related_name='tag_created_by')
          date_modified = models.DateTimeField(auto_now=True)
          modified_by = models.ForeignKey(User, related_name='tag_modified_by')
      
          def __unicode__(self):
              return self.tag
      

      Tag ModelForm:

      class TagForm(forms.ModelForm):
      
          subnet = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), required=True, queryset=Subnet.objects.all())
      
          class Meta:
              model = Tag
              exclude = ('date_created', 'created_by', 'date_modified', 'modified_by')
      

      标记views.py:

      class TagUpdateView(UpdateView):
          template_name = 'tag_update.html'
          model = Tag
          form_class = TagForm
      
          def form_valid(self, form):
      
              update_tag = form.save(commit=False)
      
              update_tag.modified_by = self.request.user
      
              update_tag.save()
      
              form.save_m2m()
      
              return super(TagUpdateView, self).form_valid(form)
      

      我的模板“tag_update.html”:

      {% extends 'base.html' %}
      {% load widget_tweaks %}
      
      {% block title %}Tag {{ object.tag }} Update{% endblock %}
      
      {% block content %}
          <h1>Tag {{ object.tag }} Update</h1>
          <br />
          <form action="" method="post" role="form">{% csrf_token %}
              <div class="row">
                  <div class="col-sm-4">
                      <div class="form-group">
                          <label for="id_tag">Tag Name</label>
                          {% render_field form.tag placeholder=form.tag.label class="form-control" %}
                      </div>
                  </div>
              </div>
              <div class="row">
                  <div class="col-sm-2">
                      <div class="form-group">
                          <label for="id_group">Group</label>
                          {% render_field form.group placeholder=form.group.label class="form-control"%}
                      </div>
                  </div>
              </div>
              <div class="row">
                  <div class="col-sm-6">
                      <div class="form-group">
                          <label for="id_description">Description</label>
                          {% render_field form.description placeholder=form.description.label class="form-control" rows="5" %}
                      </div>
                  </div>
              </div>
              <div class="row">
                  <div class="col-sm-6">
                      <div class="form-group">
                          <label for="id_checkbox">Link to Subnets</label>
                           {{ form.subnet }}
                      </div>
                  </div>
              </div>
              <br />
              <button type="submit" class="btn btn-primary">Submit</button>
          </form>
          <br />
      {% endblock %}
      

1 个答案:

答案 0 :(得分:1)

你是在思考它。如果您需要跟踪关系模型本身的信息(如创建特定子网/标记对时的修改时间戳),但是对于您在此处显示的模型关系,{处理此类关系可能会有点复杂{ {1}}就足够了 - 它为你处理m2m关系。

如果您不需要在初始表单上使用form.save_m2m(),则甚至不需要这样做,以便您可以设置commit=False字段。

对于预先填充 - 大多数情况下,我认为它应该遵循正常行为并预先填充。我可能只是使用widget类而不是显式实例化它(modified_by而不是widget=forms.CheckboxSelectMultiple),但我不明白为什么会影响它。

对于这两个问题,您可以从一个简单的widget=forms.CheckboxSelectMultiple()开始,但ModelForm上没有自定义项,只需设置subnet,就可以获得良好的结果。一旦工作,请输入特殊视图代码来处理exclude。一旦有效,请更改为modified_by的自定义窗口小部件声明 - 可能最初使用subnet窗口小部件覆盖字典而不是第一遍的自定义字段声明。