django - Django - 从模型中自动化 CRUD(DRY 方法)?
问题描述
我是 Django 新手,但不是开发新手。
我需要制作一个用户可以在其中执行 CRUD 操作(创建、读取、更新、删除)的应用程序。此功能应适用于所有模型,创建和更新的字段将从模型属性自动生成。
我所描述的几乎是管理页面附带的功能。但是,我想在我自己的应用程序中使用它,而不是使用管理应用程序。
例如,假设我们有Author
和Book
模型:
( models.py
)
from django.db import models
class Author(models.Model):
first_name = models.CharField(max_length=60)
last_name = models.CharField(max_length=60)
def __str__(self):
return self.last_name
class Book(models.Model):
title = models.CharField(max_length=60)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
def __str__(self):
return self.title
我想以上信息(模型)对于 CRUD 操作来说已经足够了,不需要为每个模型重复相同逻辑的代码。我的目标是管理页面中的功能,您所要做的就是注册您的模型。
我知道ModelForm和Generic Views,但是虽然它们有助于避免对表单字段进行硬编码,但我还没有找到一种非重复编码方法。我想避免以下方法,其中每个模型都复制相同的代码:
( forms.py
)
from django import forms
from todo.models import Author, Book
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = '__all__'
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = '__all__'
( views.py
)
from django.views.generic import CreateView
from.forms import AuthorForm, BookForm
from.models import Author, Book
class AuthorCreateView(CreateView):
model = Author
form_class = AuthorForm
...
class BookCreateView(CreateView):
model = Book
form_class = BookForm
...
那么,DRY CRUD 解决方案的最佳方法是什么(如在管理页面中)?我是否缺少任何 Django 功能?
解决方案
将我的解释放在评论中,您会得到如下信息:
from django.views import generic
from myapp.apps import MyAppConfig
from django.forms import modelform_factory
urlpatterns = []
for model in MyAppConfig.get_models():
create_url = path(
f"{model.__class___.__name__.lower()}/create",
generic.CreateView.as_view(
form_class=modelform_factory(model=model, fields='__all__'),
template_name=f"{model._meta.app_label}/create.html",
model=model
),
),
list_url = path(
f"{model.__class__.__name__.lower()}/",
generic.ListView.as_view(
template_name=f"{model._meta.app_label}/list.html",
model=model
),
),
...
urlpatterns.extend([create_url, list_url, read_url, update_url, delete_url])
所以原则是使用通用视图和模型表单工厂,生成标准的 crud 视图,从模型名称派生路径名,并在应用程序中为每个视图使用一个模板(从模型的 app_label 派生)。
使用我之前链接的文档,您应该能够将事情拼凑起来。
推荐阅读
- angular - 如何动态传递组件实例?
- java - OpenJDK 11 无法解析 javax.xml.* 属性
- javascript - 如何在代码之间使用 ActivityIndicator?
- java - 在 setter 方法中验证模型类
- c# - 使控制器方法异步会提高其性能吗?有什么好处?
- r - 如何通过给定的模式将字符串拆分为多列?
- javascript - 如何使用 javascript 获取、更改或清除 django-autocomplete-light 字段值
- google-app-engine - 通过 goroutine 异步发布到 google pub sub
- tensorflow - TensorFlow 结构搜索
- powershell - 将文件夹复制到另一个目标,根据原始创建日期命名目标文件夹