두 가지 형식이 필요한 템플릿 페이지가 있습니다. 하나의 양식 만 사용하면이 전형적인 예와 같이 문제가 없습니다.
if request.method == 'POST':
form = AuthorForm(request.POST,)
if form.is_valid():
form.save()
# do something.
else:
form = AuthorForm()
그러나 여러 양식으로 작업하려면 양식 중 하나만 제출하고 다른 양식은 제출하지 않는다는 것을 어떻게 알 수 있습니까? 일어난)?
이것은 예상 문구 와 금지 문구 가 다른 양식에 대한 제출 버튼의 이름이고 예상 문구 양식 과 금지 문구 양식이 양식 인 답변을 기반으로 한 솔루션 입니다.
if request.method == 'POST':
if 'bannedphrase' in request.POST:
bannedphraseform = BannedPhraseForm(request.POST, prefix='banned')
if bannedphraseform.is_valid():
bannedphraseform.save()
expectedphraseform = ExpectedPhraseForm(prefix='expected')
elif 'expectedphrase' in request.POST:
expectedphraseform = ExpectedPhraseForm(request.POST, prefix='expected')
if expectedphraseform.is_valid():
expectedphraseform.save()
bannedphraseform = BannedPhraseForm(prefix='banned')
else:
bannedphraseform = BannedPhraseForm(prefix='banned')
expectedphraseform = ExpectedPhraseForm(prefix='expected')
답변
몇 가지 옵션이 있습니다.
-
두 양식에 대해 다른 URL을 조치에 넣으십시오. 그런 다음 두 가지 다른 양식을 처리하기 위해 두 가지 다른보기 기능이 있습니다.
-
POST 데이터에서 제출 단추 값을 읽으십시오. 어떤 제출 버튼이 클릭되었는지 알 수 있습니다. 여러 제출 버튼을 어떻게 만들 수 있습니까?
답변
나중에 참조 할 수있는 방법은 다음과 같습니다. bannedphraseform이 첫 번째 양식이고 예상 문구가 두 번째 양식입니다. 첫 번째 것이 맞으면 두 번째 것은 건너 뜁니다 (이 경우 합리적인 가정).
if request.method == 'POST':
bannedphraseform = BannedPhraseForm(request.POST, prefix='banned')
if bannedphraseform.is_valid():
bannedphraseform.save()
else:
bannedphraseform = BannedPhraseForm(prefix='banned')
if request.method == 'POST' and not bannedphraseform.is_valid():
expectedphraseform = ExpectedPhraseForm(request.POST, prefix='expected')
bannedphraseform = BannedPhraseForm(prefix='banned')
if expectedphraseform.is_valid():
expectedphraseform.save()
else:
expectedphraseform = ExpectedPhraseForm(prefix='expected')
답변
Django의 클래스 기반 뷰는 일반적인 FormView를 제공하지만 모든 의도와 목적을 위해 하나의 양식 만 처리하도록 설계되었습니다.
Django의 일반 뷰를 사용하여 동일한 대상 작업 URL로 여러 양식을 처리하는 한 가지 방법은 아래에 표시된 것처럼 ‘TemplateView’를 확장하는 것입니다. 이 방법을 자주 사용하여 Eclipse IDE 템플릿으로 만들었습니다.
class NegotiationGroupMultifacetedView(TemplateView):
### TemplateResponseMixin
template_name = 'offers/offer_detail.html'
### ContextMixin
def get_context_data(self, **kwargs):
""" Adds extra content to our template """
context = super(NegotiationGroupDetailView, self).get_context_data(**kwargs)
...
context['negotiation_bid_form'] = NegotiationBidForm(
prefix='NegotiationBidForm',
...
# Multiple 'submit' button paths should be handled in form's .save()/clean()
data = self.request.POST if bool(set(['NegotiationBidForm-submit-counter-bid',
'NegotiationBidForm-submit-approve-bid',
'NegotiationBidForm-submit-decline-further-bids']).intersection(
self.request.POST)) else None,
)
context['offer_attachment_form'] = NegotiationAttachmentForm(
prefix='NegotiationAttachment',
...
data = self.request.POST if 'NegotiationAttachment-submit' in self.request.POST else None,
files = self.request.FILES if 'NegotiationAttachment-submit' in self.request.POST else None
)
context['offer_contact_form'] = NegotiationContactForm()
return context
### NegotiationGroupDetailView
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
if context['negotiation_bid_form'].is_valid():
instance = context['negotiation_bid_form'].save()
messages.success(request, 'Your offer bid #{0} has been submitted.'.format(instance.pk))
elif context['offer_attachment_form'].is_valid():
instance = context['offer_attachment_form'].save()
messages.success(request, 'Your offer attachment #{0} has been submitted.'.format(instance.pk))
# advise of any errors
else
messages.error('Error(s) encountered during form processing, please review below and re-submit')
return self.render_to_response(context)
html 템플릿은 다음과 같은 효과가 있습니다.
...
<form id='offer_negotiation_form' class="content-form" action='./' enctype="multipart/form-data" method="post" accept-charset="utf-8">
{% csrf_token %}
{{ negotiation_bid_form.as_p }}
...
<input type="submit" name="{{ negotiation_bid_form.prefix }}-submit-counter-bid"
title="Submit a counter bid"
value="Counter Bid" />
</form>
...
<form id='offer-attachment-form' class="content-form" action='./' enctype="multipart/form-data" method="post" accept-charset="utf-8">
{% csrf_token %}
{{ offer_attachment_form.as_p }}
<input name="{{ offer_attachment_form.prefix }}-submit" type="submit" value="Submit" />
</form>
...
답변
같은 페이지에서 독립적으로 검증 된 여러 양식이 필요했습니다. 내가 빠진 주요 개념은 1) 제출 버튼 이름에 양식 접두사를 사용하고 2) 무제한 양식이 유효성 검사를 트리거하지 않는다는 것입니다. 다른 사람에게 도움이된다면 @ adam-nelson 및 @ daniel-sokolowski의 답변과 @zeraien의 의견 ( https : //.com/a/17303480 / 2680349 ) :
# views.py
def _get_form(request, formcls, prefix):
data = request.POST if prefix in request.POST else None
return formcls(data, prefix=prefix)
class MyView(TemplateView):
template_name = 'mytemplate.html'
def get(self, request, *args, **kwargs):
return self.render_to_response({'aform': AForm(prefix='aform_pre'), 'bform': BForm(prefix='bform_pre')})
def post(self, request, *args, **kwargs):
aform = _get_form(request, AForm, 'aform_pre')
bform = _get_form(request, BForm, 'bform_pre')
if aform.is_bound and aform.is_valid():
# Process aform and render response
elif bform.is_bound and bform.is_valid():
# Process bform and render response
return self.render_to_response({'aform': aform, 'bform': bform})
# mytemplate.html
<form action="" method="post">
{% csrf_token %}
{{ aform.as_p }}
<input type="submit" name="{{aform.prefix}}" value="Submit" />
{{ bform.as_p }}
<input type="submit" name="{{bform.prefix}}" value="Submit" />
</form>
답변
Django Forms를 사용하지 않는 솔루션을 공유하고 싶었습니다. 단일 페이지에 여러 양식 요소가 있고 단일보기를 사용하여 모든 양식의 모든 POST 요청을 관리하려고합니다.
내가 한 것은 보이지 않는 입력 태그를 도입하여 매개 변수를 뷰에 전달하여 제출 된 양식을 확인할 수 있다는 것입니다.
<form method="post" id="formOne">
{% csrf_token %}
<input type="hidden" name="form_type" value="formOne">
.....
</form>
.....
<form method="post" id="formTwo">
{% csrf_token %}
<input type="hidden" name="form_type" value="formTwo">
....
</form>
views.py
def handlemultipleforms(request, template="handle/multiple_forms.html"):
"""
Handle Multiple <form></form> elements
"""
if request.method == 'POST':
if request.POST.get("form_type") == 'formOne':
#Handle Elements from first Form
elif request.POST.get("form_type") == 'formTwo':
#Handle Elements from second Form
답변
이것은 조금 늦었지만 이것이 내가 찾은 최고의 솔루션입니다. 양식 이름 및 클래스에 대한 조회 사전을 작성하고 양식을 식별하기위한 속성을 추가해야하며보기에서을 사용하여 숨겨진 필드로 추가해야합니다 form.formlabel
.
# form holder
form_holder = {
'majeur': {
'class': FormClass1,
},
'majsoft': {
'class': FormClass2,
},
'tiers1': {
'class': FormClass3,
},
'tiers2': {
'class': FormClass4,
},
'tiers3': {
'class': FormClass5,
},
'tiers4': {
'class': FormClass6,
},
}
for key in form_holder.keys():
# If the key is the same as the formlabel, we should use the posted data
if request.POST.get('formlabel', None) == key:
# Get the form and initate it with the sent data
form = form_holder.get(key).get('class')(
data=request.POST
)
# Validate the form
if form.is_valid():
# Correct data entries
messages.info(request, _(u"Configuration validée."))
if form.save():
# Save succeeded
messages.success(
request,
_(u"Données enregistrées avec succès.")
)
else:
# Save failed
messages.warning(
request,
_(u"Un problème est survenu pendant l'enregistrement "
u"des données, merci de réessayer plus tard.")
)
else:
# Form is not valid, show feedback to the user
messages.error(
request,
_(u"Merci de corriger les erreurs suivantes.")
)
else:
# Just initiate the form without data
form = form_holder.get(key).get('class')(key)()
# Add the attribute for the name
setattr(form, 'formlabel', key)
# Append it to the tempalte variable that will hold all the forms
forms.append(form)
앞으로 도움이 되길 바랍니다.
답변
클래스 기반보기와 다른 ‘액션’속성으로 접근 방식을 사용하는 경우
두 양식에 대해 다른 URL을 조치에 넣으십시오. 그런 다음 두 가지 다른 양식을 처리하기 위해 두 가지 다른보기 기능이 있습니다.
다음과 같이 오버로드 된 get_context_data
방법을 사용하여 다른 형식의 오류를 쉽게 처리 할 수 있습니다 .
views.py :
class LoginView(FormView):
form_class = AuthFormEdited
success_url = '/'
template_name = 'main/index.html'
def dispatch(self, request, *args, **kwargs):
return super(LoginView, self).dispatch(request, *args, **kwargs)
....
def get_context_data(self, **kwargs):
context = super(LoginView, self).get_context_data(**kwargs)
context['login_view_in_action'] = True
return context
class SignInView(FormView):
form_class = SignInForm
success_url = '/'
template_name = 'main/index.html'
def dispatch(self, request, *args, **kwargs):
return super(SignInView, self).dispatch(request, *args, **kwargs)
.....
def get_context_data(self, **kwargs):
context = super(SignInView, self).get_context_data(**kwargs)
context['login_view_in_action'] = False
return context
주형:
<div class="login-form">
<form action="/login/" method="post" role="form">
{% csrf_token %}
{% if login_view_in_action %}
{% for e in form.non_field_errors %}
<div class="alert alert-danger alert-dismissable">
{{ e }}
<a class="panel-close close" data-dismiss="alert">×</a>
</div>
{% endfor %}
{% endif %}
.....
</form>
</div>
<div class="signin-form">
<form action="/registration/" method="post" role="form">
{% csrf_token %}
{% if not login_view_in_action %}
{% for e in form.non_field_errors %}
<div class="alert alert-danger alert-dismissable">
{{ e }}
<a class="panel-close close" data-dismiss="alert">×</a>
</div>
{% endfor %}
{% endif %}
....
</form>
</div>