跳转到主要内容

Django的通用脚手架

项目描述

https://github.com/spapas/django-generic-scaffold/actions/workflows/gh.yml/badge.svg https://badge.fury.io/py/django-generic-scaffold.svg

使用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_nameTestModel,您可以添加以下模板

对于创建/更新,添加 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, createdelete。因此,要将详情模板名称配置为 foo.html,您将使用选项 detail_template_name = 'foo.html'

因此,模板的优先级为

  • 显式模板(如果已配置)

  • 隐式模板(如果找到)

  • 备用模板(作为最后的手段)

配置

通常,在使用 django-generic-scaffold 之前,您需要配置三件事情:用于创建和更新视图的表单类、基于通用类的视图的访问权限以及每个视图将使用的模板。这些都可以通过设置 CrudManager 类的属性来配置。

  • 要配置将要使用的表单类,请使用 form_class 选项。

  • 要设置权限,您必须将 permissions 属性设置为可调用对象组成的字典。该字典的键应该是 list, detail, update, createdelete,而值应该是类似于 login_requiredpermission_required('permission') 等可调用对象。

  • 要显式配置模板名称,请使用 action_template_name

对于任何其他生成的基于类的视图的配置,您需要定义混入(mixins),然后将这些混入作为列表传递给生成的 CBV 类,使用 action_mixins 选项(同样,操作可以是 list, detail 等)。

使用混入,您可以对自己的结果 CBV 类做任何您想做的事情——此外,通过迫使您使用混入,django-generic-scaffold 将帮助您遵循更好的代码实践(DRY)。

然而,有时混入还不够,您可能需要完全覆盖父视图来使用其他内容。为此,您可以将 action_view_class 属性设置为您的父类视图(例如,list_view_class = OverridenListView)。

API 和模板标签

如果您想在自己的模板中使用提供的模板标签,您需要在模板顶部附近添加 {% load generic_scaffold_tags %}。然后,您可以使用 set_urls_for_scaffold,这将根据您的配置输出选定脚手的 URL。此标签可以接收三个参数:django 应用程序名称、模型名称和前缀名称。您可以使用应用程序名称/模型名称的组合,或者只需使用前缀。

它将返回一个包含该模型所有脚手架 URL 的字典。例如,为了获取属于应用程序 test1 的模型 test2(注意您必须使用内部模型名称,所以对于 Test2,请使用 test2),您将使用 {% set_urls_for_scaffold "test1" "test2" as url_names %},然后您可以使用该对象的 list, create, detail, update, delete 属性来反转和获取相应的 URL,例如使用 {% url url_names.list %} 来获取列表 URL。

还有一个类似的 API 函数名为 get_url_names,您可以使用它来获取您的脚手架的 URL。

例如,您可以这样做

from generic_scaffold import get_url_names
from django.core.urlresolvers import reverse

names = get_url_names(prefix='test')
list_url = reverse(names['list'])

请注意,如果您需要使用上面的模板标签或函数并带有前缀,您需要传递参数名称,即调用它如下 {% set_urls_for_scaffold prefix="my_prefix" as url_names %}

最后,如果您出于某种原因更愿意不使用上述方法直接访问 URL 名称,您可以使用以下算法生成脚手架视图的 URL 名称:{prefix}_{app_name}_{model_name}_{method},其中方法可以是 list/create/update/detail/delete 之一。然后,您可以直接使用 {% url %}reverse

示例配置

以下是一个示例配置,它使用不同的表单(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 版本支持

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_mixinsdetail_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

这将尝试在filterstables模块中找到filters.XFiltertables.XTable类(您当然需要导入它们)。因此,如果您的模型名称是Company,它将使用CompanyFilterCompanyTable类!

现在这可以通过一些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 (30.8 kB 查看散列)

上传时间

由以下支持

AWSAWS 云计算和安全赞助商 DatadogDatadog 监控 FastlyFastly CDN GoogleGoogle 下载分析 MicrosoftMicrosoft PSF赞助商 PingdomPingdom 监控 SentrySentry 错误记录 StatusPageStatusPage 状态页面