当我将()添加到ManyToMany关系时,它是否替换以前的记录?

时间:2017-09-05 18:07:35

标签: django many-to-many

我正在为添加和编辑团队和志愿者的应用创建一组视图。志愿者可以参加任意数量的团队,其中一些团队成为团队领导者。由于需要灵活的过程(我猜),我已经将这两个项目分开了(尽管我对此有所建议!)我试图在视图上设置一致性。例如,我想确保每次在一个视图上添加团队领导时,他们也会注册为团队成员。

class Team(models.Model):
    team_name = models.CharField(max_length=30, null=True, blank=True)
    leaders = models.ManyToManyField(Volunteer, related_name='leaders', blank=True)
    enrolled = models.ManyToManyField(Volunteer, related_name='enrolled', blank=True)

class Volunteer(models.Model):
    name = models.CharField(max_length=30)

我有一个观点,我正在做这件事。保存表单后,我会将leaders中的每一个都添加到enrolled字段中。但是,当我添加它们时,我发现在字段上注册的先前值已​​被我添加的新值替换。我可以将以前的值保存在变量中并重新应用,但是它应该以这种方式工作吗?

class TeamUpdate(LoginRequiredMixin, UpdateView):
form_class = TeamCreateForm
model = Team
def form_valid(self, form):
    self.object = form.save()
    for i in self.object.leaders.all():
        self.object.enrolled.add(i)
    return HttpResponseRedirect(reverse('single', args=(self.object.id,)))
你能指出我正确的方向吗?

编辑:添加表单和模板。前者显示模型中的所有实际字段(为了简化它,我已经减少了它们,但如果您愿意,我可以发布所有字段。)

class TeamCreateForm(forms.ModelForm):
    class Meta:
        model = Team
        template_name = 'team_form.html'
        fields = '__all__'

模板:

{% extends "base.html" %}
{% block title %}Add or edit team{% endblock %}

{% block content %}

<div class="container">
  <div class="container">
    <h1 class="blue-text">add or edit team</h1>
    <form class="registration" action="" method="post">{% csrf_token %}
      {% csrf_token %}
        <div class="white row z-depth-1">
          <small class="red-text">{{ form.non_field_errors }}</small>
          <div class="col s9">
            <label for="id_name">Team Name</label>{{ form.team_name }}
            <small class="error brick-text">{{ form.team_name.errors }}</small>
          </div>
          <div class="col s12">
            <label for="id_name">Team Leaders</label>{{ form.leaders }}
            <small class="error brick-text">{{ form.leaders.errors }}</small>
          </div>
          <a class="waves-effect waves-light btn-large blue" onClick="$(this).closest('form').submit();">Save</a>
        </div>
    </form>
  </div>
</div>
{% endblock %}

1 个答案:

答案 0 :(得分:0)

您的HTML表单不包含enrolled字段,但您的ModelForm确实包含它。由于ModelForm未在enrolled字段中收到任何数据,因此它会假定您明确删除了所有选定的志愿者并将其删除。

您需要明确定义ModelForm中的哪些字段:

class TeamCreateForm(forms.ModelForm):
    class Meta:
        model = Team
        template_name = 'team_form.html'
        fields = ['team_name', 'leaders']

建议始终明确命名字段,而不是使用__all__。如果您没有添加一个不应由用户编辑的字段,则可能会出现安全问题。