Python使用模型inheritan重用视图和表单

2024-09-29 19:24:00 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,我对Python&Django相当陌生,所以这可能是一个简单的问题。现在,我有一个这样的模型:

型号.py

class Base(models.Model):
    class Meta:
        abstract = True
    # base properties

class X(Base):
    # extra props

class Y(Base):
    # extra props

然后我想得到一个X的视图和一个Y的视图,它们基本上是一样的,例如:

视图.py

class BaseView(object):
    template_name = "app/view.html"

    Type = None

    def __init__(self, type):
        self.Type = type

    def get_context_data(self, **kwargs):
        context = super(BaseView, self).get_context_data(**kwargs)
        context['data'] = get_object_or_404(self.Type, pk=kwargs["id"])
        return context


class XView(BaseView, generic.TemplateView):
    def __init__(self):
        BaseView.__init__(self, X)

class YView(BaseView, generic.TemplateView):
    def __init__(self):
        BaseView.__init__(self, Y)

网址.py

urlpatterns = [
    url(r'^xxxx/(?P<id>[0-9]+)$', views.XView.as_view(), name="view_x"),
    url(r'^yyyy/(?P<id>[0-9]+)$', views.YView.as_view(), name="view_y"),
]

像这样,我将不得不重复可能所有(或大部分)的形式,意见等,无论如何有避免这种重复?X和Y之间的差别只是django在表单中完美生成的几个字段。你知道吗

我需要根据网址区分模型,example.com/X/或者example.com/Y/其他的都差不多。你知道吗

仅供参考,使用python3,Django 1.9。你知道吗


Tags: namepyselfview视图databaseget
2条回答

您可以通过几种方法消除重复。在你的网址.py,可以将参数直接传递到视图:

# urls.py
urlpatterns = [
    url(r'^xxxx/(?P<id>[0-9]+)$', views.BaseView.as_view(Type=X), name="view_x"),
    url(r'^yyyy/(?P<id>[0-9]+)$', views.BaseView.as_view(Type=Y), name="view_x"),
]

这样,就不需要定义XViewYView。您可以更进一步,使用模型的URL参数。你知道吗

# urls.py
urlpatterns = [
    url(r'^(?P<model>\w+)/(?P<id>[0-9]+)$', views.BaseView.as_view(), name='view_base'),
]

# views.py
class BaseView(View):

    type_map = {
        'xxxx': X,
        'yyyy': Y,
    }

    def dispatch(self, request, *args, **kwargs):
        model = kwargs.get('model')
        self.type = self.type_map.get(model)
        if self.type is None:
            raise Http404
        return super(BaseView, self).dispatch(request, *args, **kwargs)

您应该按照应该使用的方式使用Django泛型视图类。如果所有类都是基于URL中的ID向模板传递对象,那么应该使用内置的DetailView类;然后可以在URLconf中直接将模型和模板名作为参数传递,而无需定义子类。你知道吗

from django.views.generic import DetailView
urlpatterns = [
    url(r'^xxxx/(?P<pk>[0-9]+)$', DetailView.as_view(model=X, template_name = "app/view.html"), name="view_x"),
    url(r'^yyyy/(?P<pk>[0-9]+)$', DetailView.as_view(model=X, template_name = "app/view.html"), name="view_y"),
]

(注意DetailView希望URL参数被称为pk,而不是id。)

如果您确实想向视图中添加更多自定义行为,那么可以将DetailView子类化;在多个URL模式中使用同一视图类仍然是完全可能的。你知道吗

相关问题 更多 >

    热门问题