0

我正在嘗試創建一個UpdateView頁面,該頁面允許我在窗體中編輯客戶信息以及所有關聯用戶的信息。我的CustomerForm工作正常,但我不確定如何設置內聯窗體集的初始數據。我試圖通過使用for循環通過self.object.user_set.all()來獲得所有用戶的字典。但是我似乎無法對UserFormSet進行任何更改。這裏是我的代碼:Django相關模型的內聯窗體集的初始數據?

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

我只想將用戶名和過期日期作爲每個formset的初始值,但訪問用戶和他們的字段似乎幾乎不可能,並且爲用戶更改值似乎沒有任何作用。

回答

0

改變你的觀點:

userList = users(
    queryset=self.object.user_set.all(), 
    instance=self.object 
) 

你也不能有request.POST在get_context_data - 這是荒謬的!從get_context_data

刪除此if self.request.POST:如果你想保存數據,你應該實現它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') 
+0

謝謝!這大部分工作。我不得不將'userFormSet'更改爲一個類變量,並將userList(from get_context_data)&inLines(from post)設置爲'self.userFormSet'。但是,提交表單會導致額外的用戶在第一次提交時被保存並提交,任何想法是什麼造成的?我嘗試將我的formset更改爲「{{f2.as_p}}',而不是我以前寫過的方式,但它不起作用。 –

+0

這是我的錯:D從'form_valid'方法中移除'form.save()'。你只需要保存'inlines' – madzohan

+0

好吧,我現在看到它是如何工作的。我保留'form.save()',否則我無法更新任何客戶信息,只是用戶。爲了避免添加額外的用戶,我設置了'extra = 0'。如果我想要提交沒有提交的附加內容,我可以更改表單集或使用「添加用戶」按鈕創建動態表單集 –

相關問題