如何在Django中的UserChangeForm中更新ManytoManyField?

问题描述

我想使用 UserChangeForm 新用户信息,除ManyToManyField之外,其他一切进展顺利。呈现页面时,我可以看到所有用户信息均按每个字段的正确顺序显示,例如用户名将在 username 字段中,但在manytomanyfield中为空白。

#model.py
class Department(models.Model):
    name = models.CharField(max_length=100)

class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(_('Email Address'),unique=True)
    department = models.ManyToManyField(Department)
    # some other fields

# forms.py
class EditUserForm(UserChangeForm):
    class Meta:
        model = CustomUser
        fields = ['email','department',..]
        widgets = {'department': forms.CheckBoxSelectMultiple()}

# view.py
def home(request):
    template_name = "app/home.html"
    edit_form = EditUserForm(instance=request.user)
       if request.method == "POST":
           edit_form = EditUserForm(request.POST,instance=request.user)
           if edit_form.is_valid():
               edit_form.save()
               return JsonResponse({'success': True},status=200)
           else:
               return JsonResponse({'error': edit_form.errors},status=400)
    return render(request,template_name,{'edit_form': edit_form})

# template
              <form action="{% url 'home' %}" method="POST">
                <div class="row">
                  {{edit_form.email}}

                  {{edit_form.first_name}}

                  {% for department in edit_form.department %}
                   <h6 id="checkBox">{{department.tag}} {{department.choice_label}}</h6>
                  {% endfor %}
                </div>
              </form>

这是图片

enter image description here

您可以看到名称和电子邮件显示在表单字段中,但是为什么所有复选框都为空? (复选框字段是部门)

解决方法

如果只想呈现该字段,则不需要for循环。您可以只使用{{edit_form.department}}。如果需要修改input中的每个CheckboxSelectMultiple字段,则应遍历edit_form.department.field.choices。 例如:

{% for choice,value in edit_form.department.field.choices %}
<input type="checkbox" name="{{choice.instance.value}}" value="{{choice.instance.pk}}" id="id_{{choice.instance.value}}">
{% endfor %}

请注意,这仅在django 3.0及更高版本中有效。

,

您需要在模板的输入中传递值和名称

{% for value,name in edit_form.fields.department.choices %}
    <input type="checkbox" name="{{name}}" value="{{value}}" id="{{name}}">
{% endfor %}