【问题标题】:Django - There's some way to avoid repeat code in all my views?Django - 有什么方法可以避免在我的所有视图中重复代码?
【发布时间】:2013-03-14 02:56:35
【问题描述】:

我项目中的所有模板都有一个注册按钮,只有当您以匿名用户身份输入时才能看到该按钮。该按钮打开一个带有两个注册表单的模式窗口。问题是我必须在我的所有视图中都有这个代码才能工作。有什么方法可以避免在我所有的视图中重复与注册表相关的代码?

澄清:在我的所有观点中重复的代码被注释为#USER REGISTRATION FORM RELATIVE 和#MERCHANT REGISTRATION FORM RELATIVE

我的模式窗口

我的观点之一(75 行):

def patrimonio_view(request, backend_registro_usuario, backend_registro_comerciante, success_url=None, form_class_usuario=None, form_class_comerciante=None,
         disallowed_url='registration_disallowed',
         template_name='home/patrimonio.html',
         extra_context=None):

#PATRIMONIO QUERYS
pat = patrimonio.objects.all()
ciu = ciudad.objects.all()

#USER REGISTRATION FORM RELATIVE
backend_registro_usuario = get_backend(backend_registro_usuario)
if not backend_registro_usuario.registration_allowed(request):
    return redirect(disallowed_url)
if form_class_usuario is None:
    form_class_usuario = backend_registro_usuario.get_form_class(request)

if "Registrar_usuario" in request.POST:
    form_class_usuario = form_class_usuario(data=request.POST, files=request.FILES)
    if form_class_usuario.is_valid():
        new_usuario = backend_registro_usuario.register(request, **form_class_usuario.cleaned_data)
        if success_url is None:
            to, args, kwargs = backend_registro_usuario.post_registration_redirect(request, new_usuario)
            return redirect(to, *args, **kwargs)
        else:
            return redirect(success_url)
else:
    form_class_usuario = form_class_usuario()

if extra_context is None:
    extra_context = {}
context = RequestContext(request)
for key, value in extra_context.items():
    context[key] = callable(value) and value() or value

#MERCHANT REGISTRATION FORM RELATIVE
backend_registro_comerciante = get_backend(backend_registro_comerciante)
if not backend_registro_comerciante.registration_allowed(request):
    return redirect(disallowed_url)
if form_class_comerciante is None:
    form_class_comerciante = backend_registro_comerciante.get_form_class(request)

if "Registrar_comerciante" in request.POST:
    form_class_comerciante = form_class_comerciante(data=request.POST, files=request.FILES)
    if form_class_comerciante.is_valid():
        new_comerciante = backend_registro_comerciante.register(request, **form_class_comerciante.cleaned_data)
        if success_url is None:
            to, args, kwargs = backend_registro_comerciante.post_registration_redirect(request, new_comerciante)
            return redirect(to, *args, **kwargs)
        else:
            return redirect(success_url)
else:
    form_class_comerciante = form_class_comerciante()

if extra_context is None:
    extra_context = {}
context = RequestContext(request)
for key, value in extra_context.items():
    context[key] = callable(value) and value() or value


#WE OBTAIN THE USERS FOR EACH GROUP
usuario_group = Group.objects.get(name="usuario").user_set.all()
comerciante_group = Group.objects.get(name="comerciante").user_set.all()

#RENDER
return render_to_response(template_name,
                          {'form_registro_usuario': form_class_usuario, 
                          'form_registro_comerciante': form_class_comerciante,
                           'patrimonio':pat, 
                           'ciudad':ciu,
                           'usuario_group': usuario_group,
                           'comerciante_group': comerciante_group,
                           },

                          context_instance=context)

解决方案 - 重构代码(29 行):

def patrimonio_view(request, 
     template_name='home/patrimonio.html'):

#PATRIMONIO QUERYS
pat = patrimonio.objects.all()
ciu = ciudad.objects.all()

if request.method == 'POST':
    if "Registrar_usuario" in request.POST:
        #USER REGISTRATION FORM RELATIVE
        return register_usuario()

    if "Registrar_comerciante" in request.POST:
        #MERCHANT REGISTRATION FORM RELATIVE
        return register_comerciante()

#WE OBTAIN THE USERS FROM EACH GROUP
usuario_group = Group.objects.get(
   name="usuario").user_set.all()
comerciante_group = Group.objects.get(
   name="comerciante").user_set.all()

#RENDER
return render_to_response(template_name,{
   'patrimonio':pat, 
   'ciudad':ciu,
   'usuario_group': usuario_group,
   'comerciante_group': comerciante_group,
}, context_instance=RequestContext(request))

【问题讨论】:

  • 注释为#USER REGISTRATION FORM RELATIVE 和#MERCHANT REGISTRATION FORM RELATIVE 的代码将存在于我的所有视图中,因为当您未登录时,可以从我的任何模板中使用模态窗口的表单。
  • 为什么不直接使用 AJAX 来处理 FORM 帖子,这样您就可以隔离视图,而不必在每个视图中嵌入所有代码?
  • 我正在搜索有关它的文档。到目前为止,这是我发现的最好的:ericwconner.com/?p=126
  • 关于 Django 和 AJAX 的 SO 问题也不少。一些搜索应该会为您提供大量示例。

标签: jquery django view registration


【解决方案1】:

如果我错过了什么,请告诉我我会修复它。抱歉,我就是看不懂其他代码。

def patrimonio_view(request, 
         backend_registro_usuario, backend_registro_comerciante, 
         form_class_usuario=None, form_class_comerciante=None,
         disallowed_url='registration_disallowed', template_name='home/patrimonio.html',
         extra_context=None, success_url=None):

    #PATRIMONIO QUERYS
    pat = patrimonio.objects.all()
    ciu = ciudad.objects.all()

    form_class_usuario = form_class_usuario()
    form_class_comerciante = form_class_comerciante()

    if request.method == 'POST':
        if "Registrar_usuario" in request.POST:
            #USER REGISTRATION FORM RELATIVE
            return user_registration(request, 
                backend_registro_usuario, 
                disallowed_url, 
                form_class_usuario, 
                success_url
                )

        if "Registrar_comerciante" in request.POST:
            #MERCHANT REGISTRATION FORM RELATIVE
            return merchant_registration(request, 
                backend_registro_comerciante, 
                disallowed_url, 
                form_class_comerciante, 
                success_url
                )

    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value


    #Obtenemos los usuarios de cada grupo
    usuario_group = Group.objects.get(
       name="usuario").user_set.all()
    comerciante_group = Group.objects.get(
       name="comerciante").user_set.all()

    #RENDER
    return render_to_response(template_name,{
       'form_registro_usuario': form_class_usuario, 
       'form_registro_comerciante': form_class_comerciante,
       'patrimonio':pat, 
       'ciudad':ciu,
       'usuario_group': usuario_group,
       'comerciante_group': comerciante_group,
    }, context_instance=context)

def user_registration(request, 
        backend_registro_usuario, form_class_usuario, 
        disallowed_url, success_url):

    backend_registro_usuario = get_backend(backend_registro_usuario)
    if not backend_registro_usuario.registration_allowed(request):
        return redirect(disallowed_url)
    if form_class_usuario is None:
        form_class_usuario = backend_registro_usuario.get_form_class(request)

    form_class_usuario = form_class_usuario(data=request.POST, 
                                            files=request.FILES)
    if form_class_usuario.is_valid():
        new_usuario = backend_registro_usuario.register(request, 
            **form_class_usuario.cleaned_data)
        if success_url is None:
            to, args, kwargs = backend_registro_usuario.post_registration_redirect(request, new_usuario)
            return redirect(to, *args, **kwargs)
        else:
            return redirect(success_url)

def merchant_registration(request, 
        backend_registro_comerciante, form_class_comerciante, 
        disallowed_url, success_url):

    backend_registro_comerciante = get_backend(backend_registro_comerciante)
    if not backend_registro_comerciante.registration_allowed(request):
        return redirect(disallowed_url)
    if form_class_comerciante is None:
        form_class_comerciante = backend_registro_comerciante.get_form_class(request)

    form_class_comerciante = form_class_comerciante(data=request.POST, 
                                                    files=request.FILES)
    if form_class_comerciante.is_valid():
        new_comerciante = backend_registro_comerciante.register(request, 
            **form_class_comerciante.cleaned_data)
        if success_url is None:
            to, args, kwargs = backend_registro_comerciante.post_registration_redirect(request, new_comerciante)
            return redirect(to, *args, **kwargs)
        else:
            return redirect(success_url)

【讨论】:

  • 非常感谢凯瑟琳!我不太确定如何在视图中使用方法。现在一切都很干净并且可以正常工作。如果您想看一下,我根据您的帮助发布了一个更加重构的版本。
【解决方案2】:

在多个视图中包含代码至少有三个选项:包含标记、上下文处理器和模板继承。这仅取决于哪一个对您的设置最有意义。

context processor 可能是将条件逻辑排除在模板之外的最佳选择,因为您需要检查用户是否是匿名的,这可以在处理器中的服务器端执行:

from django.template.loader import render_to_string

def your_context_processor(request):
    if request.user.is_anonymous():
        return {'extra_context': render_to_string('anonymous-only-content.html')}
    else:
        return {}

然后在你的模板中,你可以这样做:

{{ extra_context }}

如果填充了该变量,则需要在其中呈现仅匿名代码。这些都是简单的例子,但希望能给你一些想法。

【讨论】:

  • 感谢您的回答布兰登!我尝试使用上下文处理器来呈现包含我的表单但字段未显示且提交按钮不起作用的 html 文档:oi47.tinypic.com/2nsz4hi.jpg 当我使用 {% include %} 时也会发生同样的事情
  • 嗯。如果没有看到上下文处理器的确切实现,就很难确定为什么您的内容不会显示。如果你也尝试过使用模板标签,但它没有显示出来,你可能在代码的某个地方有一个未处理的异常,这会导致 Django 在模板层吞下这个异常。
猜你喜欢
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 2015-11-09
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多