Django相关模型的内联formset的初始数据?

时间:2015-07-01 21:24:39

标签: django django-forms django-class-based-views formset inline-formset

我正在尝试创建一个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)" />

我只是希望用户名和到期日期是每个表单集中的初始值,但访问用户及其字段似乎几乎不可能,并且更改用户的值似乎没有做任何事情。

1 个答案:

答案 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')