Django弹出式表单框架。
django-popup-forms的Python项目详细描述
问题
- 有一个简单的方式显示弹出窗口,持有任何形式, 从网站的任何页面(示例:从用户发送消息 配置文件或从配置文件列表中;从 公司名单等)
- 此弹出窗口应预先加载,即不应 向服务器发送http请求以打开弹出窗口
- 如果发生表单错误(某些字段丢失, 电子邮件格式错误等)应重新填充相同的表单 在同一页中,指示错误
- 提交表单后,应重定向用户 同一页或指定页
溶液
该解决方案由4个部分组成:
模板标记、呈现弹出窗体和打开它的链接:
{% popup_form 'id1' popup_forms.ApplyForm '/talent/apply/6/' 'popup_forms/apply_to_pool.html' %} {% popup_form 'id2' popup_forms.SomeModelForm '/talent/apply/6/' 'popup_forms/apply_to_pool.html' kwarg1=... kwarg2=... %}
视图函数的decorator,即处理弹出表单提交, 以及处理表单错误的异常:
import popup_forms @popup_forms.handler def form_view(request): if request.method == 'POST': form = ApplyForm(request.post) if not form.is_valid(): return popup_forms.OpenFormResponse(request, form) # ... # ... FORM PROCESSING GOES HERE ... # ... return popup_forms.CloseFormResponse(request) else: return redirect('failure_url') # or raise Http404 # or just popup_forms.CloseFormResponse(request)
从popup_forms/base.html派生的用于呈现表单的模板
(可选)上下文处理器(popup_forms.context_processors.popup_forms), 它将所有弹出窗体类置于上下文中,以便每次在视图中不传递它:
in settings:
POPUP_FORMS = ('messages.forms.WriteMessageForm', 'talentbutton.forms.ApplyForm', 'talentbutton.forms.ConfirmForm',)
in template it could be accessed:
{{ popup_forms.WriteMessageForm }}, etc.
decorator在页面加载时有条件地显示弹出式窗体 (例如,在注册/登录后填写一些缺少的信息):
@show_popup_form('/account/register/details/', lambda request: 'register-details' in request.session) def some_my_view(request): ...
用例如下:
模板标记与链接一起呈现表单:
<a href="..." onclick="open the form">Link Title</a> <div class="hidden_form"> <form>...</form> </div>
当用户单击“链接”时,已预先加载到模板中的表单将变得可见
用户填写表单并提交。POST请求转到表单处理URL
如果表单有效,则处理程序将返回closeformresponse 关闭弹出式窗体,用户被重定向到成功URL (默认情况下,这是显示弹出表单的引用页)
如果表单包含错误,则处理程序返回openformresponse, 它由decorator处理,decorator存储表单数据和错误数据。 在会话中,并重定向回引用视图
然后,{% popup_form %}标记找到decorator存储的数据, 并重新填充表单使其可见(不隐藏)-用户 看到相同的表单,但有错误
条件
表单处理视图没有要呈现的单独模板。 这就是为什么表单处理视图不应该呈现任何内容:它只是处理表单, 并进行重定向。如果视图呈现了某些内容,则decorator会引发异常。
缺点
- 如果页面中有许多链接,则每个链接都会隐藏呈现一个单独的表单。 但是,表单的html不占用太多空间(少于1000个字符)
- 现在我们无法将页面滚动到相同的位置 在用错误重新填充表单后,但可以解决此问题