Django形式:大多数DRY方式来组织继承模型的创建/更新表单

oma*_*mat 5 django django-forms django-class-based-views

我有2个这样的多表继承模型:

class Post(models.Model):
    title = models.CharField(max_length=100, blank=True, null=True)
    text = models.TextField(blank=True, null=True)
    location = models.PointField()
    ...

class BlogPost(Post):
    blog = models.ForeignKey(Blog)
Run Code Online (Sandbox Code Playgroud)

同样,BlogPost的表单类也继承自PostForm类:

class PostForm(MapModelForm):
    ...
    class Meta:
        model = Post

    def clean(self):
        ...

class BlogPostForm(PostForm):
    class Meta:
        model = BlogPost
Run Code Online (Sandbox Code Playgroud)

我曾经在两个非基于类的视图中处理两个模型的创建/更新.为了让事情变得干燥,我决定尝试给Django基于类的通用视图.但由于缺乏相关文件的例子和用户不友好以及各种方法,我很困惑.

我们的想法是为Post模型提供基于类的表单视图,并为其继承它们BlogPost.我该如何定制视图类?

我应该有单独的PostCreate和PostUpdate视图吗?然后这两个类几乎完全相同,而不是DRY.

我是否应该单独FormView更新/创建帖子?它适用于创建,但我无法弄清楚如何进行更新.

我应该使用提供的mixin类而不是直接从视图继承来构建自定义视图(或创建/更新的两个视图)吗?

Gar*_*ees 8

你是对的,基于类的视图文档是相当原始的.毫无疑问,它会有所改善,但目前你需要准备好进行实验和阅读来源.

你正在尝试做两件事:

  1. 找到一种使用类来组织视图的好方法.
  2. 重构您的代码以避免重复.

一次解决这些问题非常重要.找出正确的类层次第一,只有然后找出如何分解出的重复.

我们快去吧.您的类层次结构将如下所示:

from django.views import generic

class PostCreateView(generic.CreateView):
    form_class = PostForm
    model = Post

class PostUpdateView(generic.UpdateView):
    form_class = PostForm
    model = Post

class BlogPostCreateView(generic.CreateView):
    form_class = BlogPostForm
    model = BlogPost

class BlogPostUpdateView(generic.UpdateView):
    form_class = BlogPostForm
    model = BlogPost
Run Code Online (Sandbox Code Playgroud)

这涉及很多重复,但现在很清楚如何分解其中的一些:

from django.views import generic

class PostView(generic.FormView):
    form_class = PostForm
    model = Post

class PostCreateView(PostView, generic.CreateView): pass
class PostUpdateView(PostView, generic.UpdateView): pass

class BlogPostView(PostView):
    form_class = BlogPostForm
    model = BlogPost

class BlogPostCreateView(BlogPostView, generic.CreateView): pass
class BlogPostUpdateView(BlogPostView, generic.UpdateView): pass
Run Code Online (Sandbox Code Playgroud)

如果您仍然不满意这里的重复次数,您可以进一步自动构建这些类(使用type在运行时创建类).但是,这可能是一个太过分了,直到你完全习惯使用基于类的视图.