2017-09-05 1 views
1

Je crée un ensemble de vue pour une application qui ajoute et édite des équipes et des bénévoles. Les volontaires peuvent faire partie d'autant d'équipes qu'ils le souhaitent, et certains d'entre eux sont placés en tant que chefs d'équipe. En raison du besoin de flexibilité du processus (je suppose), j'ai laissé les deux éléments séparés (je suis ouvert aux suggestions à ce sujet, bien que!) Et j'essaie d'uniformiser les points de vue. Par exemple, je veux m'assurer que chaque fois que j'ajoute un chef d'équipe sur une vue, ils sont également inscrits comme membres de l'équipe.Lorsque j'ajoute() à une relation ManyToMany, remplace-t-elle les enregistrements précédents?

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) 

J'ai une vue sur laquelle je fais juste ceci. Après avoir enregistré le formulaire, je prends chacun des leaders et les ajoute au champ enrolled. Cependant, quand je les ajoute, je trouve que les valeurs précédentes d'inscrits sur le terrain ont été remplacées par les nouvelles valeurs que j'ai ajoutées. Je pourrais simplement enregistrer les valeurs précédentes dans une variable et réappliquer, mais est-ce censé fonctionner de cette façon?

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,))) 

Pouvez-vous me diriger dans la bonne direction?

Modifier: ajouter la forme et le modèle. La première montre tous les champs réels du modèle (je les ai réduits pour vous simplifier la tâche, mais je peux tout afficher si vous préférez).

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

Modèle:

{% 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

L'ajout ne devrait pas remplacer les relations existantes. Comment vérifiez-vous les valeurs de inscrits? – arjun27

+0

Pouvez-vous montrer 'TeamCreateForm'? – knbk

+0

@knbk C'est ajouté. Vous pouvez voir que c'est un ModelForm assez standard. –

Répondre

0

Votre formulaire HTML ne comprend pas enrolled champ, mais votre ModelForm ne l'inclure. Étant donné que ModelForm ne reçoit aucune donnée dans le champ enrolled, il suppose que vous avez explicitement supprimé tous les volontaires sélectionnés et les supprimez.

Vous devez définir explicitement quels champs sont dans votre ModelForm:

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

Il est recommandé de toujours nommer explicitement les champs au lieu d'utiliser __all__. Si vous ne le faites pas et que vous ajoutez un champ qui ne devrait pas être modifié par les utilisateurs, cela peut devenir un problème de sécurité.

+0

Vous avez dit la vérité. C'était le problème. Merci beaucoup! –