可以在多个应用程序中重用基于函数的视图而无需复制代码吗?

时间:2016-05-29 16:56:08

标签: django

我有许多具有类似功能的基于功能的视图

例如,创建,列出,编辑视图和搜索公司和联系人:客户,供应商和制造商。

我可以重复使用相同的模型,其中所有3个都使用少量布尔标志。 但我想知道如何以最佳方式处理视图和模板以避免代码重复。 (目前我在思考但是大量使用控制-H但感觉不对)

(我很遗憾现在没有使用基于类的视图,但为时已晚)

2 个答案:

答案 0 :(得分:3)

通过传入url参数来实现重用,可以做很多事情。你的想象力和一致性在这里会有很多帮助:

举个简单的例子:

urlpatterns = [
    url(r'^add-customer/$', create, {'template':'customer.html'}, name='create_customer'),
    url(r'^add-vendor/$', create, {'template':'vendor.html'}, name='create_vendor'),
    url(r'^add-manufacturer/$', create, {'template':'manufacturer.html'}, name='create_manufacturer'),
    ...

和视图:

def create(request, template):
    #use template as you like, coming from url conf.
    return render(request, template)
    ...

当你想到它时,这可能是正常的代码。一个更有趣的例子:

from someapp.forms import *
from someapp.models import *
urlpatterns = [
    url(r'^customer/$', create, {'template':'customer.html', 'form_class':customer_form}, name='create_customer'),
    url(r'^vendor/$', create, {'template':'vendor.html', 'form_class':vendor_form}, name='create_vendor'),
    url(r'^manufacturer/$', create, {'template':'manufacturer.html', 'form_class':manufacturer_form}, name='create_manufacturer'),
    ...

和视图:

def create(request, template, form_class):
    #use template as you like, coming from url conf.
    form = form_class()#
    return render(request, template)
    ...

仍然是非常普通的代码。你可以变得时髦并动态生成网址:

在你的urls.py中:

for form_class in (CustomerForm, VendorForm, ManufacturerForm): #model forms
    model = form_class._meta.model
    model_name = model._meta.module_name
    urlpatterns += url(r'^create/$', create, {'template':'%s.html' % model_name, 'form_class':form_class, 'model':model}, name='create_%s' % model_name),

并在视图中:

def create(request, template, form_class, model):
    #use template as you like, coming from url conf.
    form = form_class()#

    return render(request, template)

您可以将pks传递给模型并编写如下代码:

def create(request, form_class, model, id=None):
    instance = get_object_or_404(model, pk=id) if id else None
    edited = True if instance else False
    if request.method == 'POST':
        form = form_class(data=request.POST, files=request.FILES, instance=instance)
        if form.is_valid():
            instance = form.save()
            ...
    else:
        form = form_class(instance=instance)
    return render(request, template_name, {'form': form, 'instance': instance})

希望你有胃。

答案 1 :(得分:1)

答案当然取决于模型之间的实际差异。但是,如果你可以抽象你的视图函数"使用一些布尔标志"我建议将它们放在一个中心位置,可能是您应用或项目中的常见文件,例如abstract_views.py

然后您只需要以有意义的方式调度视图函数:

import my_app.abstract_views
from .models import Model1, Model2

def model1_create_view(request):
    abstract_views.create(request, model=Model1)

def model2_create_view(request):
    abstract_views.create(request, model=Model2)

在这个密码示例中,create将是用于创建实例的抽象视图函数,并且需要参数model以及要对其进行操作的实际模型。

增加:

或者,根据要求使用布尔标志:

import my_app.abstract_views

def model1_create_view(request):
    abstract_views.create(request, is_customer=True)

def model2_create_view(request):
    abstract_views.create(request, is_vendor=True)

使用布尔标志时,请记住定义如果某人同时是客户和供应商会发生什么......

抽象视图的定义如下所示:

def abstract_view(request, is_customer=False, is_vendor=False):
    context = do_something (is_customer, is_vendor)
    return(render(request, 'app/template.html', context))

希望有所帮助。