我正在尝试创建一个UpdateView页面,该页面允许我编辑客户的信息以及所有附属用户'表格中的信息。我的CustomerForm工作正常,但我不确定如何设置内联表单集的初始数据。我尝试使用for循环通过self.object.user_set.all()
获取所有用户的字典。但是我似乎无法对UserFormSet进行任何更改。这是我的代码:
forms.py
class CustomerForm(ModelForm):
class Meta:
model = Customer
fields = ['name', 'system', 'bill_amount', 'exchanges', 'due_date', 'invoice_date', 'keycodes_expire', 'paid_date', 'active']
success_url = reverse_lazy('index')
UserFormSet = inlineformset_factory(Customer, User, fields=['name', 'expiration_date'], extra=1, can_delete=True)
models.py
class Customer(models.Model):
active = models.BooleanField(default = False)
bill_amount = models.DecimalField(max_digits=7, decimal_places=2)
due_date = models.DateField(default = timezone.now() + timedelta(days=30), blank = True, null = True)
exchanges = models.IntegerField(default = 0)
invoice_date = models.DateField(default = timezone.now(), blank = True, null = True)
keycodes_expire = models.DateField(default = timezone.now() + timedelta(days=120), blank = True, null = True)
name = models.CharField(max_length = 128)
paid_date = models.DateField(default = timezone.now() + timedelta(days=30), blank = True, null = True)
edge_hosted = 'Edge (hosted)'
edge_nonhosted = 'Edge (non-hosted)'
edge_risk_hosted = 'Edge Risk (hosted)'
edge_risk_nonhosted = 'Edge Risk (non-hosted)'
tradepad = 'Tradepad'
system_choices = (
(edge_hosted, 'Edge (hosted)'),
(edge_nonhosted, 'Edge (non-hosted)'),
(tradepad, 'Tradepad'),
(edge_risk_hosted, 'Edge Risk (hosted)'),
(edge_risk_nonhosted, 'Edge Risk (non-hosted)')
)
system = models.CharField(max_length=64, choices = system_choices, default = edge_hosted)
def get_absolute_url(self):
return reverse('customer-detail', kwargs={'pk': self.pk})
class User(models.Model):
customer = models.ForeignKey('Customer')
expiration_date = models.DateField(default = timezone.now() + timedelta(days=120))
name = models.CharField(max_length = 64, default = 'user')
views.py
class CustomerUpdate(generic.UpdateView):
model = Customer
form_class = CustomerForm
template_name_suffix = '_update_form'
success_url = reverse_lazy('index')
def get_context_data(self, **kwargs):
userData = []
for x in range(0,len(self.object.user_set.all())):
foo = {'name' : self.object.user_set.all()[x].name, 'expiration_date' : self.object.user_set.all()[x].expiration_date}
userData.append(foo)
users = inlineformset_factory(Customer, User, fields=['name', 'expiration_date'], extra=len(self.object.user_set.all()), can_delete=True)
userList = users(queryset = self.object.user_set.all())
ctx = super(CustomerUpdate, self).get_context_data(**kwargs)
if self.request.POST:
ctx['inlines'] = userList
else:
ctx['inlines'] = userList
return ctx
customer_update_form.html
<h1>Update Customer</h1>
<form id="customer_form" action="" method="post">{% csrf_token %}
{% for f in form %}
<div>{{ f.label }}:<br />{{ f }}
{% if f.errors %}
{% for v in f.errors %}
<br /><span style="color:red;">{{ v }}</span>
{% endfor %}
{% endif %}
</div>
{% endfor %}
<h2>Update User(s)</h2>
<table>
{% for f2 in inlines %}
<tr id="{{ f2.prefix }}-row-0">
<td>
{{ f2.name.label }}:
{{ f2.name }}
{% if f2.name.errors %}
<span style="color:red;">{{ f2.name.errors }}</span>
{% endif %}
</td>
</tr>
<tr id="{{ f2.prefix }}-row-1">
<td>
{{ f2.expiration_date.label }}:
{{ f2.expiration_date }}
{% if f2.expiration_date.errors %}
<span style="color:red;">{{ f2.expiration_date.errors }}</span>
{% endif %}
</td>
</tr>
<tr id="{{ f2.prefix }}-row-2">
<td>
{{ f2.DELETE.label }}?
{{ f2.DELETE }}
{% if f2.DELETE.errors %}
<span style="color:red;">{{ f2.DELETE.errors }}</span>
{% endif %}
</td>
</tr>
{{ f2.as_p }}
{% endfor %}
</table>
{{ inlines.management_form }}
<input type="submit" value="Create Customer / User(s)" />
我只是希望用户名和到期日期是每个表单集中的初始值,但访问用户及其字段似乎几乎不可能,并且更改用户的值似乎没有做任何事情。
答案 0 :(得分:0)
更改您的观点:
userList = users(
queryset=self.object.user_set.all(),
instance=self.object
)
你也不能在get_context_data中拥有request.POST - 这是荒谬的!从if self.request.POST:
get_context_data
如果您想保存数据,则应在post method
def post(self, request, *args, **kwargs):
if self.pk_url_kwarg:
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
inlines = users(request.POST, request.FILES, instance=self.object)
else:
form = self.form_class(request.POST)
inlines = users(request.POST, request.FILES)
if form.is_valid() and inlines.is_valid():
return self.form_valid(form, inlines)
else:
return self.form_invalid(form, inlines)
def form_valid(self, form, inlines):
if not self.object:
self.object = form.save()
else:
form.save()
inlines.instance = self.object
inlines.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, inlines):
return self.render_to_response(
self.get_context_data(
form=form,
inlines=inlines
)
)
def get_success_url(self):
return reverse('some_app:url_name')