代码是我的书签(用于按类别管理书签的项目)的视图部分。它使用Python3.4/Django 1.6。我还包括了models.py作为参考。
代码执行以下操作
我主要关心的是摘要的质量。其他评论也是受欢迎的,但我主要关注的是守则的结构。
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,
})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发布于 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本身中调用。还请注意,将方法分组的另一种方法是将它们放在一个单独的文件中。
总的来说,我认为只有静态方法的类不是很好。最好将它们转换为最高级别的常规功能,或在其专用文件中转换为常规功能。GetBookmarks和GetCategories也是如此。对于只包含一个公共方法的类尤其如此。
回到您的主要问题:此类类并不代表有用的抽象,它们是相关方法的简单分组。实用工具类是有用的,但是如果在它们中只有一个方法,那么它们就有点过火了,而且可能帮不了那么多忙。
有几件事不是很毕不过,或者是可以改进的。
而不是这样:
if ids\_string == '': return []
用这种方式写起来更像毕达通:
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:
def _get_json(cur_objects, func):
return json.dumps([func(cur_object) for cur_object in cur_objects])类似于早些时候:
if exclude\_value != "": # ...
Pythonic的方法是:
if exclude_value:
# ... 这比需要的复杂得多:
data = Autocomplete.\_get\_json( objects, lambda x: getattr(x, attr\_name) )
由于_get_json函数将简单地调用元素上的lambda,因此在这里使用简单的列表理解并将列表传递给_get_json而不需要lambda就更自然了:
data = Autocomplete._get_json([getattr(x, attr_name) for x in objects])既然我们知道_get_json有多简单,我们就可以完全绕过它:
data = json.dumps([getattr(x, attr_name) for x in objects])https://codereview.stackexchange.com/questions/54745
复制相似问题