Pythonic 的方式来简化这个长 Django 视图



我正在编写一个视图,该视图驱动博客文章编辑页面上的"提交"按钮。此视图将从博客文章编辑页面上的表单中捕获 POST 数据,并更新与该博客文章关联的 Post 对象。

我对 Django 相当陌生,对 Python 也不那么陌生,所以我不确定简化此视图的最佳方法。

只是为了让这更容易理解,draft这就是我在编辑上下文中所说的博客文章。我现在拥有的代码(全文转载如下)有一系列 3 个块,如下所示:

try:
    new_title = request.POST['post_title']
except (KeyError):
    return render_to_response('blog/edit.html', {
        'draft': draft,
        'error_msg': "That's weird. You didn't provide a" +
                        "post title in the POST arguments.",
        }, context_instance=RequestContext(request))
draft.title = new_title
# Here goes some code specific to handling updating the title

如您所见,基本上,此块只是尝试获取 POST 数据,如果不能,它会重定向回编辑页面并显示错误消息。

由于此视图基本上执行相同的操作 3 次,因此违反了 DRY 原则。我正在尝试找到解决此问题的方法。将此代码分离到另一个函数中的问题在于,错误处理进程需要向视图的调用方返回一些内容。我应该把它分开并检查返回值的类型吗?干净吗?我不必向函数传递大量参数吗?这被认为是不好的形式吗?

另外,如果您有任何其他改进此代码样式或设计的技巧,我将不胜感激,因为我是一个非常 Python/Django 新手。

非常感谢!


现在的完整视图代码:

def save_changes(request, draft_id):
    draft = get_object_or_404(Post, pk=draft_id)
    # Get the new title
    try:
        new_title = request.POST['post_title']
    except (KeyError):
       return render_to_response('blog/edit.html', {
            'draft': draft,
            'error_msg': "That's weird. You didn't provide a" +
                            "post title in the POST arguments.",
            }, context_instance=RequestContext(request))
    draft.title = new_title
    if draft.slug = None:
        draft.slug = unique_slugify(draft.title)
    # Get the new text
    try:
        new_text = request.POST['post_text']
    except (KeyError):
        return render_to_response('blog/edit.html', {
            'draft': draft,
            'error_msg': "That's weird. You didn't provide" +
                            "post text in the POST arguments.",
            }, context_instance=RequestContext(request))
    draft.text = new_text
    # Get the new publication status
    try:
        new_published_status = request.POST['publish']
    except (KeyError):
        return render_to_response('blog/edit.html', {
            'draft': draft,
            'error_msg': "That's weird. You didn't provide a" +
                            "publication status in the POST arguments."
    if new_published_status != draft.published:
        if draft.published:
            draft.published = False
            draft.pub_date = None
        else:
            draft.published = True
            draft.pub_date = timezone.now()
    draft.save()
    return HttpResponseRedirect(reverse('blog.views.edit', args=draft.id))

一个简单的列表理解将解决您的问题。

error_messages = {'post_title':'post title','post_text':'post text','publish':'publication status'}
errors = [error_messages[key] for key in ('post_title','post_text','publish') if not request.POST.has_key(key)]

这将为您提供错误消息名称的列表。 然后,您可以编写一个错误部分,其中包含错误列表并决定如何处理它(例如显示所有错误,显示第一个错误,甚至根据缺少多少错误对消息的语法进行一些花哨的逻辑)。

我可以推荐 Django 中的 Forms 对象来为你做验证吗?

相关内容

  • 没有找到相关文章

最新更新