2015-09-04 46 views
1

我在编辑/更新具有manytomany字段的表单时遇到问题。我不知道如何实现用于保存多个字段的表单的逻辑。模型山姆是一个用户,他管理不同的账户,并在一段时间内管理的账户发生变化。因此,应该灵活地添加或删除他通过Samprofileupdateform管理的帐户,该帐户包含一个用于帐户的manytomany字段。你能帮我实施吗?如何通过Django窗体编辑/更新模型并添加许多字段?

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

回答

1

我创造了这个自定义视图功能来创建/更新/修改用户资料管理多个帐户/客户。我通过Intermediate模型创建了两个模型Sam和Account之间的ManytoMany关系。中间模型是SamAccount。请为模型找到以下代码,查看功能和表格。现在这个问题已经解决了。

形式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'), 
      ) 
     ) 

查看功能:

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

型号帐户:

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

模型山姆:

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 

中间模型用于处理两个模型之间的ManyToMany关系。如果必须在两个模型之间创建关系,我所要做的就是在中间模型中为相应的外键字段创建一个对象。

中间模型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

如果我正确理解您的问题:您想要显示具有ManyToMany字段的模型的一种形式。问题是,如果山姆有3个账户,你想显示3个字段,但它可能更少或更多。

我最近做了类似的事情。在窗体的初始化,查询该模型并遍历结果所拥有的账户中的每个对象添加到self.fields阵列

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