在编辑/更新具有manytomany字段的表单时,我遇到了一个问题。我不知道如何实现保存具有manytomany字段的表单的逻辑。模型Sam是一个用户,他管理不同的帐户,并且在一段时间内他管理的帐户发生变化。因此,应该灵活地添加或删除他通过Samprofileupdateform管理的帐户,其中包括Account的多个字段。你能帮我解决一下这个问题吗?
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 %}
答案 0 :(得分:1)
如果我正确理解您的问题:您想要显示具有ManyToMany字段的模型的表单。问题是如果Sam有3个帐户,你想要显示3个字段,但它可能更少或更多。
我最近做了类似的事情。在表单的init中,查询此模型拥有的帐户并循环结果以将每个对象添加到self.fields
数组
query = ... # query Sam's accounts
for account in query:
self.fields[account.accnt_nagp] = forms.IntegerField(...)
答案 1 :(得分:1)
您应该使用模型formset来添加/删除相关帐户。
https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#model-formsets
答案 2 :(得分: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