我有两个非常相似的观点。我怎样才能超级"他们?

时间:2014-08-20 15:46:27

标签: django django-templates django-views

我正在尝试设计一个Django应用程序,以促进音乐家之间乐器的借出。

我有一个模板页面,其中包含发布借阅或借阅工具的表单,以及另一个包含搜索可用商家信息表单的模板。

除了呈现的模板(设计和按钮略有不同)之外,两个视图之间的差异是它们添加到上下文中的表单的名称(即PostForm()SearchForm()

基本上,我有两个视图几乎完全相同的代码。这通常是不好的做法。

有什么办法可以将两个视图合并到一个超级视图中。排序,以便自动对两个视图进行更改?我希望尽可能避免重复的代码。

1 个答案:

答案 0 :(得分:1)

使用基于类的视图(CBV)非常容易。

例如,您可以在django.views.generic.FormView

中使用views.py,如下所示
from django.views import generic

class ClassyFormView(generics.FormView):  # Of course name the view whatever you like
    # Note that I'm not setting any of the specific attributes here
    # As I am planning on overriding this view for each form's specifics

    # This is where you may override methods of the FormView
    def get_context_data(self, *args, **kwargs):
        """ This method allows you to edit the context passed to the template """

        context = super(ClassyFormView, self).get_context_data(*args, **kwargs)  # Get context from FormView

        # Add variables to the context data
        context['message'] = "Hello World!"

        return context

    def form_valid(self, form):
        """ 
        This method is called once the form has been instantiated with 
        POST data and has been validated
        """

        # Do whatever you want after the form is validated
        print(form.cleaned_data['some_field'])

    def form_invalid(self, form):
        # Do something if the form is invalid
        pass

然后,您可以覆盖自定义类,以维护它对FormView执行的特定操作,但使用正确的表单类:

class SearchFormView(ClassyFormView):
    form_class = SearchForm

class PostFormView(ClassyFormView):
    form_class = PostForm

请注意,您可以(也可能会)设置prefixsuccess_urltemplate_name等字段,并覆盖大量可能有用的其他方法!< / p>

请注意,如果您的表单为ModelForm,那么您可能希望使用特定于模型的通用表单视图之一,例如CreateViewUpdateView。使用这些将允许您访问表单正在作用的对象。因此,在课程中设置正确的模型后,您的form_valid方法可能如下所示:

def form_valid(self, form):
    self.object = form.save(commit=False)
    # Do stuff here to the object before you save it
    # Such as altering or setting fields
    self.object.some_field = "I'm a string"
    self.object.save()

我无法解释有关CBV的所有,甚至是基于类的表单视图,所以请务必再查看文档

Django Class-Based-View Inspector是一个非常棒的网站,似乎没有多少人知道!通常比潜入源代码更容易。

相关的Django文档:


决定添加一些可能有帮助的细节。

通用视图指定其类属性的默认值,但除非您真的泛型,否则通常最好覆盖它们。关于具体属性的一些解释:

  • prefix指定表单的前缀。在使用多种形式的情况下很有用。
    • 默认为None
    • 如果您需要更高级的逻辑,可以通过在get_prefix()方法中返回前缀来设置前缀。
  • success_url指定表单成功时重定向到的位置。对于模型表单视图,这将默认为模型的get_absolute_url()
    • 可以通过在get_success_url()方法
    • 中返回成功网址来设置
  • template_name指定视图在获取请求时显示的模板的名称
    • 可以通过在get_template_name()方法中返回模板名称进行设置。

配置CBV的URL也很简单。使用as_view()方法,如下所示:

url(r'^some_url/', SearchFormView.as_view(), name="some-url")