Django模型的声明性注释和预取

prepared-properties的Python项目详细描述


Django制备特性

Django模型的声明性注释和预取。在

我们经常会发现自己写了很多非常复杂的注释 预取。当这些在整个项目中使用时,定义它们的逻辑 在queryset方法中有点隐藏(如果注释 相互依赖)。如果有默认/原始实现作为属性, 这种逻辑完全不同。使用这些注释 要求您调用这些queryset方法中的每一个,这会很快变得有点 一团糟。在

这个包试图通过允许您定义注释和 预取为“prepared”属性,因此您可以通过 引用class属性。querysetprepare方法解析 注释依赖项并为您构建正确的查询集。在

需要Python3.6和django 2.2。它可能适用于django3,但我没有 试过了(欢迎使用PRs<;3)

带注释的特性

要添加带注释的属性,只需传入 注释到AnnotatedProperty类或annotated_property 装饰工。然后可以通过调用prepare(Model.propery_name)来准备它 在queryset。在

避免在注释中循环引用模型(例如,通过引用 模型属性在注释中处于启用状态),也可以将注释传递为 lambda,将在注释queryset时对其求值。在

当您使用decorator时,将使用您装饰的方法体 当注释不存在时。使用它会发出警告,建议您 使用prepare查询集方法。在

fromdjango.db.modelsimportModel,Sum,OuterRef,Managerfromprepared_propertiesimportannotated_property,AnnotatedProperty,PropertiedQuerySetclassBook(Model):page_number=models.PositiveIntegerField()classAuthor(Model):objects=Manager.from_queryset(PropertiedQuerySet)()pages_written=AnnotatedProperty(Subquery(Book.objects.filter(author=OuterRef("pk")).values("author").annotate(pages_written=Sum("page_number")).values("page_number")))# ... or with a default getter:@annotated_property(Subquery(Book.objects.filter(author=OuterRef("pk")).values("author").annotate(pages_written=Sum("page_number")).values("page_number")))defpages_written(self):# a warning is emitted before this is run.returnself.book_set.aggregate(pages_written=Sum("page_number"))["pages_written"]forauthorinAuthor.objects.prepare(Author.pages_written):print(author.pages_written)

相关注释属性

通常,注释可能依赖于其他注释的存在。如果你通过了 属性构造函数或修饰符中的属性名数组 当您准备 使用另一个属性:

^{pr2}$

现在调用Book.objects.prepare(Author.twice_the_pages_written)也将 注释Book.pages_written。这允许您更改底层 在不更改queryset定义的情况下实现注释 到处都是。尼托。在

预取属性

对于预取,也可以执行类似的、但功能不完整的操作:

classAuthor(Model):objects=Manager.from_queryset(PropertiedQuerySet)()short_books=PrefetchedProperty("book_set",Book.objects.filter(page_number__lt=100))forauthorinAuthor.objects.prepare(Author.pages_written):print(author.short_books)

由于预取不能相互依赖,depends_onkwarg不是 支持预取。目前也不支持默认的getter (django在执行 预取,它将始终执行天真的getter。)

正如您所看到的,prepare方法并不关心传递它是预取还是 注释,因此属性可以从注释更改为预取,反之亦然 不需要更改queryset定义或模型接口!在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
JavaPax考试:从非标准Maven存储库解析Karaf特性存储库(XML文件)   java Spring启动Bean创建异常   java中将ArrayList转换为数组的方法   Android Studio的java Unity插件。   java在CheckStyle中从方法计数中排除getter和setter   HibernateJava。sql。SQLSyntaxErrorException:表/视图“序列”不存在   与命令行程序Java vs C通信   java WebView膨胀异常   java在O(n)java8流中寻找两个列表的交集   java使用Gradle运行单元测试时,最大堆大小在哪里设置?   ssl加载java应用程序(CXF)内的jks文件   CI:Jenkins Git:Simple Java项目:希望在特定时间在脚本上发送消息   java根据位置更改数字   java按数值排序字符串数组   macos java版本“1.6.0_65”是否与java 6模棱两可?   Cassandra中的java时间戳