首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >管理书签的个人项目.查看部件

管理书签的个人项目.查看部件
EN

Code Review用户
提问于 2014-06-19 17:44:16
回答 1查看 181关注 0票数 5

代码是我的书签(用于按类别管理书签的项目)的视图部分。它使用Python3.4/Django 1.6。我还包括了models.py作为参考。

代码执行以下操作

  • 提供相关的自动完成JSON数据
  • 提供类别/书签的详细信息(都是我项目的DB模型)
  • 打开存储在书签中的网站

我主要关心的是摘要的质量。其他评论也是受欢迎的,但我主要关注的是守则的结构。

views.py

代码语言:javascript
复制
from django.http import HttpResponse
from django.shortcuts import render

from BookMarker.models import BookMark, Category

import json
import webbrowser


###########################
##       Auxiliary       ##
###########################
def _get_objects_by_params(request, param_name, object_class):
    ids_string = request.GET.get(param_name, '')
    if ids_string == '':
        return []
    ids = ids_string.split(',')
    return [object_class.objects.get(pk=_id) for _id in ids]


class Autocomplete():
    @staticmethod
    def _get_json(cur_objects, func):
        results = []
        for cur_object in cur_objects:
            results.append(func(cur_object))
        return json.dumps(results)

    @staticmethod
    def autocomplete(request, class_name, attr_name):
        term = request.GET.get('term', '')
        objects = class_name.objects.filter(**{
            attr_name + '__icontains': term
        })

        exclude_value = request.GET.get("excludes", "")
        if exclude_value != "":
            objects = objects.exclude(id__in=[int(i) for i in exclude_value.split(",")])

        data = Autocomplete._get_json(
            objects,
            lambda x: getattr(x, attr_name)
        )
        return HttpResponse(data, 'application/json')


class GetBookMarks:
    @staticmethod
    def get_bookmarks_by_categories(categories):
        bookmarks = set()
        for category in categories:
            bookmarks.update(category.bookmark_set.all())
        return bookmarks

    @staticmethod
    def get_bookmark_by_name(bookmark_name):
        return BookMark.objects.filter(name=bookmark_name)[0]


class GetCategories:
    @staticmethod
    def get_categories_by_bookmark(bookmark):
        return bookmark.category.all()


###########################
##         Services      ##
###########################
def category_autocomplete(request):
    return Autocomplete.autocomplete(request, Category, 'name')


def bookmark_autocomplete(request):
    return Autocomplete.autocomplete(request, BookMark, 'name')


def website_open(request):
    cur_url = _get_objects_by_params(request, 'id', BookMark)[0].url_content
    webbrowser.open(cur_url)
    return HttpResponse('success', 'text/html')


def get_bookmarks(request):
    categories = _get_objects_by_params(request, 'value', Category)
    bookmarks = GetBookMarks.get_bookmarks_by_categories(categories)
    return render(request, 'BookMarker/partials/bookmarks.html', {
        'bookmarks': bookmarks,
    })


#TODO Need to check the name
def get_bookmark_by_name(request):
    bookmark = GetBookMarks.get_bookmark_by_name(request.GET.get("name", ""))
    categories = GetCategories.get_categories_by_bookmark(bookmark)
    result = [category.name for category in categories]
    return HttpResponse(json.dumps(result), 'application/json')


def get_category(request):
    category = Category.objects.get(name=request.GET.get('value', ''))
    return render(request, 'BookMarker/partials/category.html', {
        'category': category,
    })

models.py

代码语言:javascript
复制
from django.db import models


class Category(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class BookMark(models.Model):
    name = models.CharField(max_length=50)
    url_content = models.CharField(max_length=500)
    category = models.ManyToManyField(Category)

    def __str__(self):
        return self.name
EN

回答 1

Code Review用户

回答已采纳

发布于 2014-12-21 06:34:21

总的来说,这篇文章写得很好。

抽象与代码结构

我主要关心的是摘要的质量。其他评论也是受欢迎的,但我主要关注的是守则的结构。

模型很好,很简单,没有评论。

视图文件中的类不是很好。因为它们只有静态方法,所以它们本质上是实用程序类。因此,这些方法根本不需要在类中,它们可以是简单的顶级函数。例如,这类呼叫有点尴尬:

return Autocomplete.autocomplete(request, Category, 'name')

通常情况下,类应该帮助您避免重复术语。例如,Person类将有一个get_name方法而不是get_person_name。因为类已经暗示了Person,所以它中的方法不需要重复术语"person“。像Autocomplete.autocomplete这样的调用的存在是类结构问题的一个症状。

可能您为Autocomplete创建了一个类来隐藏私有方法_get_json。这主意不错。但是,由于该方法只从autocomplete本身调用,所以它也可以在autocomplete本身中调用。还请注意,将方法分组的另一种方法是将它们放在一个单独的文件中。

总的来说,我认为只有静态方法的类不是很好。最好将它们转换为最高级别的常规功能,或在其专用文件中转换为常规功能。GetBookmarksGetCategories也是如此。对于只包含一个公共方法的类尤其如此。

回到您的主要问题:此类类并不代表有用的抽象,它们是相关方法的简单分组。实用工具类是有用的,但是如果在它们中只有一个方法,那么它们就有点过火了,而且可能帮不了那么多忙。

编码实践

有几件事不是很毕不过,或者是可以改进的。

而不是这样:

if ids\_string == '': return []

用这种方式写起来更像毕达通:

代码语言:javascript
复制
    if not ids_string:
        return []

而不是这样:

def \_get\_json(cur\_objects, func): results = [] for cur\_object in cur\_objects: results.append(func(cur\_object)) return json.dumps(results)

常用的方法是使用列表理解,这使其更加紧凑和Pythonic:

代码语言:javascript
复制
    def _get_json(cur_objects, func):
        return json.dumps([func(cur_object) for cur_object in cur_objects])

类似于早些时候:

if exclude\_value != "": # ...

Pythonic的方法是:

代码语言:javascript
复制
        if exclude_value:
            # ... 

这比需要的复杂得多:

data = Autocomplete.\_get\_json( objects, lambda x: getattr(x, attr\_name) )

由于_get_json函数将简单地调用元素上的lambda,因此在这里使用简单的列表理解并将列表传递给_get_json而不需要lambda就更自然了:

代码语言:javascript
复制
        data = Autocomplete._get_json([getattr(x, attr_name) for x in objects])

既然我们知道_get_json有多简单,我们就可以完全绕过它:

代码语言:javascript
复制
        data = json.dumps([getattr(x, attr_name) for x in objects])
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/54745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档