2017-09-05 5 views
1

チームやボランティアを追加、編集するアプリのビューのセットを作成しています。ボランティアはできるだけ多くのチームに参加することができ、そのうちいくつかはチームのリーダーになります。プロセスの柔軟性の必要性(私は推測する)のために、私は両方の項目を分離したままにしておきました(私はこれについて提案しています!)、私はビューに一貫性を設定しようとしています。たとえば、チームリーダーを1つのビューに追加するたびにチームメンバーとして登録されるようにしたいと考えています。ManyToMany関係に()を追加すると、以前のレコードが置き換えられますか?

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 %} 
+0

既存のリレーションを置き換えるべきではありません。あなたはどのように登録したのですか? – arjun27

+0

'TeamCreateForm'を表示できますか? – knbk

+0

@knbk追加されました。あなたはそれがかなり標準的なModelFormであることがわかります。 –

答えて

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__を使用してのフィールドに名前を付けることをお勧めします。そうしないと、ユーザーが編集すべきでないフィールドを追加すると、セキュリティ上の問題になる可能性があります。

+0

あなたは真実を語っています。これが問題でした。どうもありがとうございました! –

関連する問題