5

forms.py của tôi:Làm thế nào để sử dụng hai biểu mẫu Django khác nhau ở cùng một mẫu?

class AlertForm(forms.ModelForm): 
class Meta: 
    model=Alert 
    fields = ('high','medium', 'user') 
    widgets = { 
     'user': forms.HiddenInput() 
    } 

AlertCountFormset = modelformset_factory(Alert, 
             form = AlertForm) 

Một lớp Mẫu Django:

class NotifierForm(forms.ModelForm): 
high = forms.ChoiceField(choices=NOTIFIER_TYPE) 
medium = forms.ChoiceField(choices=NOTIFIER_TYPE) 
low = forms.ChoiceField(choices=NOTIFIER_TYPE) 

def save(self, commit=True): 
    alert = super(NotifierForm, self).save(commit=False) 
    alert.high = self.cleaned_data["high"] 
    alert.medium = self.cleaned_data["medium"] 
    alert.low = self.cleaned_data["low"] 
    alert.save() 
    return alert 

class Meta: 
    model=Notifier 
    fields = ('high','medium', 'low', 'user') 
    widgets = { 
     'user': forms.HiddenInput() 
    } 

NotifierFormset = modelformset_factory(Notifier, 
            form = NotifierForm) 

Dưới đây là dành cho các lĩnh vực lựa chọn:

NOTIFIER_TYPE = (
(0, _('E-mail')), 
(1, _('Skype')), 
(2, _('IRC')) 
) 

Tôi muốn để điền vào hai hình thức đồng bản mẫu. Vì vậy, tôi chọn để viết quan điểm tương tự cho cả hai ví dụ:

def profile_setting(request, slug): 
if request.method == 'POST': 
    alert_form = AlertForm(request.POST) 
    notifier_form = NotifierForm(request.POST) 
    if alert_form.is_valid() and notifier_form.is_valid(): 
     alert = alert_form.save(commit=False) 
     notifier = notifier_form.save(commit=False) 
     alert.user = request.user.username 
     notifier.user = request.user.username 
     notifier.save() 
     alert.save() 
     return HttpResponseRedirect(reverse('profile_setting', args=[slug])) 

extra_context = { 
    'alert_form': AlertForm(), 
    'notifier_form': NotifierForm() 
} 
return direct_to_template(request,'users/user_profile_setting.html', 
          extra_context) 

Theo rằng trong template.html tôi:

{% block content %} 
<h3>{% trans "Alerts limit" %}</h3> 
<form action="" method="POST">{% csrf_token %} 
    {{ alert_form.as_p }} 
    <input type="submit" value="{% trans 'Update' %}" /> 
</form> 

<h3>{% trans "Notifier setting" %}</h3> 
<form action="" method="POST">{% csrf_token %} 
    {{ notifier_form.as_p }} 
    <input type="submit" value="{% trans 'Update' %}" /> 
</form> 

Mọi thứ đều đúng, ta lưu dữ liệu đến cơ sở dữ liệu cũng có. Nhưng vấn đề là bất cứ khi nào tôi điền aler_form và bấm vào buttone cập nhật. nó cũng cập nhật biểu mẫu khác với cùng giá trị hoặc ngược lại. Ví dụ: nếu tôi chọn

1 2 3 for high , medium and low for alert_Form 

Sau đó, nó cũng lưu cùng một giá trị cho notify_form. Tại sao chuyện này đang xảy ra. Đó có phải là một cái gì đó sai trái với quan điểm?

Trả lời

12

Sử dụng đối số prefix để các tên trường của bạn không xung đột.

Ví dụ:

alert form = AlertForm(request.POST, prefix='alert') 
notifier_form = NotifierForm(request.POST, prefix='notifier') 

Bạn cần phải sử dụng tiền tố tương tự ở hình thức không liên kết của bạn.

extra_context = { 'alert_form': AlertForm(prefix='alert'), notifier_form': NotifierForm(prefix='notifier') } 

Lợi thế của việc sử dụng tiền tố là bạn không cần đổi tên trường theo cách thủ công, như umnik700 đề xuất trong câu trả lời của họ.

+0

Ngoài những thay đổi đó. tôi có nên thay đổi mẫu bên cạnh hay không? –

+0

Không, bạn không cần thực hiện bất kỳ thay đổi nào đối với mẫu. – Alasdair

+0

Sau khi thêm. Chẳng có gì xảy ra. Ý tôi là, không có giá trị nào được nhập vào cơ sở dữ liệu. Thậm chí không có lỗi –

3

Vấn đề là trên biểu mẫu của bạn, các trường có cùng tên.

yêu cầu.POST là một đối tượng giống như từ điển. Vì vậy, nó chỉ chứa các cặp tên/giá trị từ yêu cầu. Nếu tên trường giống nhau trên cả hai biểu mẫu thì khi bạn gọi

alert_form = AlertForm(request.POST) 
notifier_form = NotifierForm(request.POST) 

chúng được khởi tạo với cùng giá trị. Để giải quyết điều này, hãy đặt tên cho duy nhất giữa hai biểu mẫu của bạn. Ví dụ, tiền tố tất cả các tên trường trên AlertForm với "alert_".

+0

Xin lỗi, tôi không có bạn. Hai cái tên nào? –

+0

Cảm ơn bạn đã trả lời :) Một điều nữa. Điều này có thể trong Django-Form, bất cứ khi nào tôi sẽ cập nhật tất cả các lĩnh vực của tôi trong các hình thức. Tất cả các trường sẽ hiển thị giá trị đã lưu trước đó trong cơ sở dữ liệu. –

+1

Có, điều đó là có thể. Extra_context chứa hai trường hợp biểu mẫu. Họ theo cách bạn làm điều đó ngay bây giờ là bạn vượt qua các hình thức chưa được khởi tạo. Nếu bạn muốn hiển thị dữ liệu bạn cần để initalize chúng. –