Django的通用脚手架
项目描述
使用django-generic-scaffold,您可以快速为模型创建CRUD通用基于类的视图,这样您只需编写几行额外的代码即可拥有模型的基本CRUD界面!与django-admin相比,此CRUD界面的目的是供用户使用,而不是供工作人员使用。
django-generic-scaffold与其他脚手架工具不同,因为它通过创建普通django基于类的视图的子类(而不是输出python代码)在运行时生成所有视图/URL路由。这样,您可以在任何需要时重新配置您的视图。
如您所理解的,此库的主要目的是以尽可能少的脑力劳动为项目中的尽可能多的模型添加CRUD。当然,django-admin在这方面无与伦比,但通常您不希望将/admin的访问权限授予所有进行数据录入的用户。我发现这个项目对我的工作非常有价值(我主要创建供公共部门组织内部使用的应用程序);我想,当您需要为项目创建快速MVP时,它也应该非常有用。
示例
我已经添加了一个使用django-generic-scaffold的示例项目: https://github.com/spapas/generic-scaffold-demo
安装
使用 pip install django-generic-scaffold 安装,或者如果你想使用GitHub上的最新版本,请尝试 pip install git+https://github.com/spapas/django-generic-scaffold。
如果您想使用 django-generic-scaffold 的模板标签和备用模板,请将 generic_scaffold 添加到您的 INSTALLED_APPS 设置中。如果您不需要模板标签或备用模板,则不需要修改设置,直接使用即可!
简单用法
假设您在 models.py 中定义了一个名为 Book 的模型。在您的 views.py 或更好的是在名为 scaffolding.py 的模块中,定义一个覆盖 CrudManager 的类
from generic_scaffold import CrudManager
import models
class BookCrudManager(CrudManager):
model = models.Book
prefix = 'books'
现在,将以下行包含到您的应用的 urls.py 中
from scaffolding import BookCrudManager # or from views import BookCrudManager depending on where you've put it
book_crud = BookCrudManager()
# [...] define your urlpatters here
urlpatterns += book_crud.get_url_patterns()
现在,您可以通过访问 http://127.0.0.1:8000/books(或您的 prefix)来获取您的 Book 实例列表。以下方法也已创建
创建: http://127.0.0.1:8000/bookscreate
详情: http://127.0.0.1:8000/booksdetail/<id>
编辑: http://127.0.0.1:8000/booksupdate/<id>
删除: http://127.0.0.1:8000/booksdelete/<id>
如果不做任何其他操作,将使用默认的备用模板(它们很丑,应该仅用于测试)。您应该添加一个名为 app_name/testmodel_list.html 的模板(这是 ListView 的默认模板)来覆盖备用模板 - 请参阅下一节以获取更多相关信息。
您为 BooksCrudManager 方法设置的 prefix 选项将仅将该前缀添加到所有创建的URL之前,也可以用于获取反向URL的名称。
模板选择
有一系列备用模板,如果没有其他模板可以使用,将使用这些模板。这些模板仅用于测试目的,应该被覆盖(除非您想快速查看是否一切正常)。现在,有两种方法可以重新定义您的模板
隐式:只需添加适当的模板,根据您的应用程序/模型名称(类似于正常基于类的视图),例如对于 app_name 和 TestModel,您可以添加以下模板
对于创建/更新,添加 app_name/testmodel_form.html,对于列表,添加 app_name/testmodel_list.html,对于详情,添加 app_name/testmodel_detail.html,对于删除,添加 app_name/testmodel_confirm_delete.html。
显式:您可以使用 action_template_name 配置选项来显式设置每个操作的模板。操作可以是 list, detail, update, create 或 delete。因此,要将详情模板名称配置为 foo.html,您将使用选项 detail_template_name = 'foo.html'。
因此,模板的优先级为
显式模板(如果已配置)
隐式模板(如果找到)
备用模板(作为最后的手段)
配置
通常,在使用 django-generic-scaffold 之前,您需要配置三件事情:用于创建和更新视图的表单类、基于通用类的视图的访问权限以及每个视图将使用的模板。这些都可以通过设置 CrudManager 类的属性来配置。
要配置将要使用的表单类,请使用 form_class 选项。
要设置权限,您必须将 permissions 属性设置为可调用对象组成的字典。该字典的键应该是 list, detail, update, create 或 delete,而值应该是类似于 login_required 或 permission_required('permission') 等可调用对象。
要显式配置模板名称,请使用 action_template_name。
对于任何其他生成的基于类的视图的配置,您需要定义混入(mixins),然后将这些混入作为列表传递给生成的 CBV 类,使用 action_mixins 选项(同样,操作可以是 list, detail 等)。
使用混入,您可以对自己的结果 CBV 类做任何您想做的事情——此外,通过迫使您使用混入,django-generic-scaffold 将帮助您遵循更好的代码实践(DRY)。
然而,有时混入还不够,您可能需要完全覆盖父视图来使用其他内容。为此,您可以将 action_view_class 属性设置为您的父类视图(例如,list_view_class = OverridenListView)。
示例配置
以下是一个示例配置,它使用不同的表单(TestForm),通过创建和更新时的混入定义不同的行为,并需要登录用户才能更新/删除/创建(但匿名用户可以列出和查看详情):
from django.contrib.auth.decorators import login_required
class TestCrudManager(CrudManager):
prefix = 'test'
model = models.TestModel
form_class = forms.TestForm
create_mixins = (CreateMixin, )
update_mixins = (UpdateMixin, )
permissions = {
'update': login_required,
'delete': login_required,
'create': login_required,
}
支持的 Django/python 版本
从tox.ini中可以看出,测试是为Python 2.7与Django 1.8-1.11以及Python 3.8和Python 3.11与Django 1.11-4.2运行的,因此这些都是支持的版本。中间版本也应无问题运行。
Python 版本 |
Django 版本 |
---|---|
2.7 |
1.8-1.11 |
3.8+ |
1.11-4.2 |
关于django-generic-scaffold的一些技巧
以下是一些更多的技巧和建议,以更好地使用此包
对于一个名为Company的模型,我会使用前缀“companies/”(注意最后的斜杠)。一开始这可能有些奇怪,但它创建出看起来很不错的URL,例如:/companies/(列表),/companies/detail/3(详情)等。
为您的模型添加一个get_absolute_url方法,以避免在创建/编辑实例后成功提交时声明重定向位置。例如,对于相同的Company模型,我会这样做:
from generic_scaffold import get_url_names
class Company(models.Model):
def get_absolute_url(self):
return reverse(get_url_names(prefix='companies/')['detail'], args=[self.id])
继续上述Company示例,您可以在与公司相关的模板中添加以下模板标签:
{% load generic_scaffold_tags %}
[...]
{% set_urls_for_scaffold prefix="companies/" as co_url_names %}
然后您就可以像这样访问URL: {% url co_url_names.list %} 或 {% url co_url_names.detail %}。
如上所述,如果您出于某种原因更愿意直接访问URL名称,可以使用以下算法生成: {prefix}_{app_name}_{model_name}_{method}。因此,对于我们的Company示例,如果应用名称为core,则列表视图的名称将是companies/_core_company_detail(注意前缀是companies/)。
有时django-generic-scaffold会创建比您想要的更多视图!例如,出于各种原因,我通常避免使用删除视图。对于小型模型,您可能不需要详情视图。要“禁用”一个视图,您可以使用以下简单的mixin:
from django.core.exceptions import PermissionDenied
class NotAllowedMixin(object, ):
def get_queryset(self):
raise PermissionDenied
然后当您定义您的CrudManager时,将其用作方法中的mixin,例如,如果您想禁用删除,您将添加:delete_mixins = (NotAllowedMixin, )。我想如果CrudManager有一种方法可以实际定义需要哪些方法会更好,但这种解决方案(对我而言)要简单得多(:))。
如果您想更改创建/更新视图中出现的字段,您需要定义一个form_class。如果没有它,所有字段都将可见。
您可能需要修复查询以避免n+1问题。这可以通过以下mixin轻松实现:
class FixQuerysetMixin(object, ):
def get_queryset(self):
return super(FixQuerysetMixin, self).get_queryset().select_related(
'field1', 'field2'
)
然后您可以将此mixin添加到您的CrudManager对应的list_mixins或detail_mixins列表中。
我的列表视图始终使用一个表格(来自https://github.com/jieter/django-tables2)和一个过滤器(来自https://github.com/carltongibson/django-filter)。如果您想将DRY原则提升到下一个层次,您可以将以下mixin添加到您的CrudManager的list_mixins中,以自动将表格和过滤器添加到列表视图中:
import filters, tables
class AddFilterTableMixin(object, ):
def get_context_data(self, **kwargs):
context = super(AddFilterTableMixin, self).get_context_data(**kwargs)
qs = self.get_queryset()
filter = getattr(filters, self.model.__name__+'Filter')(self.request.GET, qs)
table = getattr(tables, self.model.__name__+'Table')(filter.qs)
RequestConfig(self.request, paginate={"per_page": 15}).configure(table)
context['table'] = table
context['filter'] = filter
return context
这将尝试在filters和tables模块中找到filters.XFilter和tables.XTable类(您当然需要导入它们)。因此,如果您的模型名称是Company,它将使用CompanyFilter和CompanyTable类!
现在这可以通过一些type魔法来进一步实现DRY,即时生成表格和过滤器类;然而,我得出的结论是,您几乎总是需要配置它们以定义在表格中显示哪些字段以及在过滤器中使用哪些字段,因此我认为这并不真正值得。
变更日志
v.0.5.7
将Django 4.1和4.2添加到tox.ini
版本 v.0.5.6
将 Django 4.0 添加到 tox.ini
版本 v.0.5.5
将 Django 3.0 添加到 tox.ini
版本 v.0.5.4
将 Django 2.2 添加到 tox.ini
停止支持 Django < 1.8
版本 v.0.5.3
将 Django 2.1 添加到 tox.ini
版本 v.0.5.2
上传说明文档到 PyPI
版本 v.0.5.0
添加对 Django 2 的支持
版本 v.0.4.1
添加对 Django 1.11 的支持
版本 v.0.4.0
添加对 Django 1.10 的支持
允许覆盖所有视图的父类
版本 v.0.3.3
修复 django 1.9 不包含 (url) patterns 函数的 bug
版本 v.0.3.2
包含模板到 pip 包中(旧版本由于错误的 setup.py 配置而没有包含它们)
版本 v.0.3.1
修复添加 form_class 时 '.__all__' 字段的 bug
版本 v.0.3.0
停止支持 Django 1.4 和 1.5
为 Django 1.8 和 1.9 添加对 Python 3(Python 3.5)的支持
版本 v.0.2.0
API 和模板标签的重大变更
添加示例项目
添加对 Django 1.9 的支持和配置 tox
添加了一组回退模板(generic_scaffold/{list, detail, form, confirm_delete}.html)
使用 API(get_url_names)进行测试,并将其添加到文档中
将 (url) 前缀作为属性添加到 CrudManager,并修复 templatetag 以使用它。
前缀必须唯一,以便更容易使用 API 和模板标签
模型也必须是唯一的
版本 v.0.1.2
添加测试并与 tox 集成
添加一些基本模板(非空,主要用于测试)
版本 v.0.1.1
添加模板标签以获取 CRUD URL
版本 v.0.1
初始版本
项目详情
django-generic-scaffold-0.6.0.zip 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | a5e46b0dded2e08578b62f6da8433feb071dc4da605e8ef0e716117fe1dc5c13 |
|
MD5 | a5c57631c4563c752485cd14f5acf29b |
|
BLAKE2b-256 | 3baad5c0c86f640635135b39619d0ec7218a38003e06b413c94c80b8f991485d |