【问题标题】:Possible to make these two django views DRY-er?可以使这两个 django 视图干燥吗?
【发布时间】:2016-03-03 11:37:48
【问题描述】:

我目前正在通过一些培训来学习 Python / Django 堆栈以构建博客。

我目前有两个类似的视图用于添加新帖子和编辑现有帖子(post_new 和 post_edit),如下所示:

def post_new(request):
    if request.method == "POST":
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.published_date = timezone.now()
            post.save()
            return redirect("post_detail", pk=post.pk)      
    else:
        form = PostForm()    
    return render(request, "blog/post_edit.html", {"form": form})


def post_edit(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user 
            post.published_date = timezone.now()
            post.save()
            return redirect("post_detail", pk=post.pk)
    else:
        form = PostForm(instance=post)
    return render(request, "blog/post_edit.html", {"form":form})

尽管这些视图执行不同的工作,但它们共享一些相同的代码。

试图遵循最佳实践(DRY),有没有一种明智的方法可以使这种类似的观点变得 DRYer?还是将这种长度的视图保留为长格式以使其易于阅读更好?

【问题讨论】:

    标签: python django python-3.x django-views dry


    【解决方案1】:

    我个人会这样写:

    def post_edit(request, pk=None):
        if pk is not None:
            post = get_object_or_404(Post, pk=pk)
        else:
            post = None
        if request.method == "POST":
            form = PostForm(request.POST, instance=post)
            if form.is_valid():
                post = form.save(commit=False)
                post.author = request.user 
                post.published_date = timezone.now()
                post.save()
                return redirect("post_detail", pk=post.pk)
        else:
            form = PostForm(instance=post)
        return render(request, "blog/post_edit.html", {"form":form})
    

    基本上,您将默认的instance 值传递给ModelForm

    【讨论】:

      【解决方案2】:

      您可能想为此使用Class-based views

      from django.views.generic.edit import CreateView, UpdateView
      
      class PostCreate(CreateView):
          model = Post
          fields = ['name', ...]
      
      class PostUpdate(UpdateView):
          model = Post
          fields = ['name', ...]
      

      【讨论】:

      • 切换到基于类的视图并不能解决重复代码问题。除非您创建 mixin,否则设置作者和发布日期的代码将被复制。这不一定比 Gert 建议的单个函数更好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 2010-11-26
      相关资源
      最近更新 更多