2016-01-22 56 views
1

首先,我對Python很陌生& Django,所以它可能是一個簡單的問題。現在,我有這樣一個模型:Python重複使用模型繼承的視圖和表單

models.py

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

class X(Base): 
    # extra props 

class Y(Base): 
    # extra props 

然後我想有X和Y的一個視圖中的一個,這將基本上做同樣的,例如:

views.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) 

urls.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在表單中完美生成的幾個字段。

我需要根據URL,example.com/X/或example.com/Y/來區分模型,其餘的差不多相同。

僅供參考,使用Python 3,Django 1.9。

回答

1

您可以通過幾種方法刪除重複項。在你的urls.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) 
+0

真棒謝謝你!這是我一直在尋找的。 @DanielRoseman也是對的,不需要子類(我剛剛意識到這一點)。我會做這個選項,因爲我仍然需要自定義行爲。 –

+0

它應該是'return super(BaseView,self)'''return'丟失。這樣,它就像一個魅力:) –

2

您應該按照它們應該使用的方式使用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模式中使用相同的視圖類仍然是完全可能的。