2015-09-04 1 views
1

Je suis confronté à un problème lors de l'édition/mise à jour d'un formulaire avec un champ manytomany. Je ne sais pas comment implémenter la logique pour enregistrer un formulaire avec un champ manytomany. Le modèle Sam est un utilisateur, qui gère différents comptes et sur une période de temps les comptes qu'il gère changent. Il devrait donc y avoir de la flexibilité dans l'ajout ou la suppression des comptes qu'il gère via le Samprofileupdateform qui inclut un champ manytomany pour Account. Pouvez-vous s'il vous plaît m'aider comment mettre en œuvre cela?Comment éditer/mettre à jour un modèle via Django avec un champs manytomany?

models.py

class Account(models.Model): 
    accnt_nagp = models.CharField(max_length=30, unique=True, primary_key=True) 
    #sam_name = models.ManyToManyField(Sam) 
    def __unicode__(self): 
    return self.accnt_nagp 

class Sam(models.Model): 
    SUNNYVALE = 'SVL' 
    NORTHCAROLINA = 'RTP' 
    EUROPE = 'EMEA' 
    INDIA = 'NB' 
    AUSTRALIA = 'AUS' 
    suppaccntmgr = 'SAM' 
    MANAGER = 'SAM_MGR' 
    REGION_CHOICES = (
     (SUNNYVALE, 'Sunnyvale'), 
     (NORTHCAROLINA, 'RTP'), 
     (EUROPE,'EMEA'), 
     (INDIA,'NB'), 
     (AUSTRALIA,'AUS'), 
    ) 
    DESIGNATION_CHOICES = (
     (suppaccntmgr, 'SAM'), 
     (MANAGER, 'SAM_MGR'), 
    ) 
    user = models.OneToOneField(User) 
    designation = models.CharField(max_length=8, choices=DESIGNATION_CHOICES, 
         default=suppaccntmgr) 
    mgr = models.ForeignKey(SamMgr) 
    accnt = models.ManyToManyField(Account) 

    def __unicode__(self): 
     return u'%s' % self.user.username 

Views.py:

class SamProfileUpdateView(views.LoginRequiredMixin, UpdateView): 
    model = Sam 
    form_class = SamProfileUpdateForm 
    success_url = reverse_lazy('risklist') 
    template_name = 'samrunbook/samaccntassociate.html' 

forms.py

class SamProfileUpdateForm(forms.ModelForm): 
    class Meta: 
     model = Sam 
     fields = ('accnt','mgr') 
    def __init__(self, *args, **kwargs): 
     super(SamProfileUpdateForm, self).__init__(*args, **kwargs) 
     self.helper = FormHelper(self) 
     self.helper.form_method = 'POST' 
     self.helper.form_class = 'form-horizontal' 
     self.helper.label_class = 'col-md-3' 
     self.helper.field_class = 'col-md-6' 
     self.helper.layout = Layout(
      'accnt', 
      'mgr', 
      FormActions(
       Submit('map', 'Map Your Account', css_class="btn-primary col-md-offset-3 col-md-6") 
       ) 
     ) 

templates.py

{% extends 'samrunbook/base_risk.html' %} 
{% load crispy_forms_tags %} 

{% block content %} 
<h3 class="col-md-offset-5">Login | Risk Register</h3> 
{% csrf_token %} 
{% crispy form %} 
{% endblock %} 

Répondre

1

J'ai créé cette fonction de vue personnalisée pour créer/mettre à jour/modifier un profil d'utilisateur de gérer plusieurs comptes/clients. Je l'ai fait via le modèle Intermediate pour créer les relations ManytoMany entre les deux modèles Sam et Account. le modèle intermédiaire est SamAccount. Veuillez trouver le code ci-dessous pour les modèles, la fonction de visualisation et également le formulaire. Le problème est résolu maintenant.

forme AccountMapForm:

class AccountMapForm(forms.Form): 
    account_nagp = forms.CharField() 

    def __init__(self, *args, **kwargs): 
     super(AccountMapForm, self).__init__(*args, **kwargs) 
     self.helper = FormHelper() 
     self.helper.form_class = 'form-horizontal' 
     self.helper.label_class = 'col-md-4' 
     self.helper.field_class = 'col-md-6' 
     self.helper.layout = Layout(
      Field('account_nagp', css_class='input-xlarge'), 
      FormActions(
       Submit('save_changes', 'Map', css_class='btn-primary col-md-offset-1 col-md-4'), 
       Submit('un_map', 'UnMap', css_class='btn-primary col-md-offset-1 col-md-4'), 
      ) 
     ) 

Voir Fonction:

def account_map(request, slug): 
    user_id = slug 
    sam = Sam.objects.get(user_id=user_id) 
    sam_check = SamAccount.objects.filter(sam=sam) 
    message_account_map = "Please enter the Account Nagp you want to Map to your Profile" 
    message_account_unmap = "Account is succesfully UnMapped" 
    message_account_map_success = 1 
    message_account_unmap_success = 1 
    if 'save_changes' in request.POST: 
     print "yes save_changes is there" 
    if 'un_map' in request.POST: 
     print "Yes Unmap is there" 
    if request.method == 'POST': 
     form = AccountMapForm(request.POST) 
     if form.is_valid(): 
      user_id = slug 
      account_from_form = form.cleaned_data['account_nagp'] 
      try: 
      account = Account.objects.get(accnt_nagp=account_from_form) 
      try: 
       if 'save_changes' in request.POST: 
        account = SamAccount.objects.get(sam=sam, account=account_from_form) 
        message_account_map = "Account is already Mapped" 
        message_account_map_success = 0 # To get the color change for the Warning 
       else: 
        SamAccount.objects.get(sam=sam, account=account_from_form).delete() 
        message_account_unmap_success = 0 
      except ObjectDoesNotExist: 
       if 'save_changes' in request.POST: 
        SamAccount.objects.create(sam=sam, account=account) 
        message_account_map = "Account is succesfully Mapped to your profile" 
       else: 
        message_account_unmap = "The requested Account was not mapped to your profile" 
        message_account_unmap_success = 1 
      except ObjectDoesNotExist: 
      account = Account.objects.create(accnt_nagp=account_from_form) 
      SamAccount.objects.create(sam=sam, account=account) 
      message_account_map = "Created the Account and succesfully Mapped to your profile" 
    else: 
     form = AccountMapForm() 
     template = loader.get_template('book/account_map.html') 
     context = RequestContext(request, { 
      'form' : form, 
      'message_account_map' : message_account_map, 
      'message_account_unmap' : message_account_unmap, 
      'message_account_map_success' : message_account_map_success, 
      'message_account_unmap_success' : message_account_unmap_success, 
    }) 
    return HttpResponse(template.render(context)) 

Modèle compte:

class Account(models.Model): 
    """Each Account Can have multiple SAMs""" 
    accnt_nagp = models.CharField(max_length=30, unique=True, primary_key=True) 
    sam_name = models.ManyToManyField('Sam', related_name='managed_by', through='SamAccount') 
    def __unicode__(self): 

modèle Sam:

class Sam(models.Model): 
    """Sam can have Multiple Accounts""" 
    SUNNYVALE = 'SVL' 
    NORTHCAROLINA = 'RTP' 
    EUROPE = 'EMEA' 
    INDIA = 'NB' 
    AUSTRALIA = 'AUS' 
    ROLE = 'SAM' 
    MANAGER = 'SAM_MGR' 
    REGION_CHOICES = (
    (SUNNYVALE, 'Sunnyvale'), 
    (NORTHCAROLINA, 'RTP'), 
    (EUROPE,'EMEA'), 
    (INDIA,'NB'), 
    (AUSTRALIA,'AUS'), 
    ) 
    DESIGNATION_CHOICES = (
    (ROLE1, 'SAM'), 
    (MANAGER, 'SAM_MGR'), 
    ) 
    user = models.OneToOneField(User) 
    designation = models.CharField(max_length=8, choices=DESIGNATION_CHOICES,  default=ROLE) 
    mgr = models.ForeignKey(SamMgr) 
    slug = models.SlugField(max_length=255) 
    accnt = models.ManyToManyField(Account, related_name='accounts_managed', through='SamAccount') 

    def __unicode__(self): 
     return u'%s' % self.user.username 

Modèle intermédiaire pour gérer la relation ManyToMany entre les deux modèles. Si vous devez créer une relation entre les deux modèles, tout ce que j'ai à faire est de créer un objet dans le modèle Intermédiaire pour les champs de clé étrangère correspondants.

Modèle intermédiaire SamAccount:

class SamAccount(models.Model): 
    account = models.ForeignKey('Account', on_delete=models.CASCADE) 
    sam = models.ForeignKey('Sam', on_delete=models.CASCADE) 

    def __unicode__(self): 
     return u'%s' % self.account 
1

Si je comprends bien votre problème: vous voulez afficher une forme d'un modèle qui a un champ ManyToMany. Le problème est que si Sam a 3 comptes, vous voulez afficher 3 champs, mais c'est peut-être moins ou plus.

J'ai fait quelque chose comme ça récemment. Dans votre init formulaire, interrogez les comptes appartenant à ce modèle et boucle sur les résultats pour ajouter chaque objet dans le tableau self.fields

query = ... # query Sam's accounts 
for account in query: 
    self.fields[account.accnt_nagp] = forms.IntegerField(...)