django-queryset的多态遗传

django-polymorphic-queryset的Python项目详细描述


django多态查询集

帮助实现依赖于模型类型的筛选逻辑。

不应混淆筛选和权限检查。如果您需要根据用户获取项目,您可能应该 使用django权限。

安装

pip install django-polymorphic-queryset

动机

例如,您的应用程序有两个模型:Product并从中派生出来PerishableProduct

fromdjango.dbimportmodelsclassProduct(models.Model):name=models.CharField(max_length=120)classPerishableProduct(Product):is_perished=models.BooleanField(default=False)classBrokenProduct(Product):repaired=models.BooleanField(default=False)

如果要添加返回active产品(未损坏和修复的产品)的视图 这个层次结构可能以一个包含所有条件的函数结束:

fromdjango.dbimportmodelsclassProductQuerySet(models.QuerySet):defget_active_products(self):returnself.filter(perishableproduct__is_perished=False,brokenproduct__repaired=True)

在具有许多模型和条件的大型应用程序中,此函数可能变得复杂且难以维护。 此外,通过这个实现,queryset将知道派生模型的详细信息。

可在并行层次结构中分离queryset筛选器方法,以便派生的queryset将添加自定义逻辑 以方法为基础或覆盖它们:

# Not a real example, just the idea.fromdjango.dbimportmodelsclassProductQuerySet(models.QuerySet):defget_active_products(self):returnself.all()classPerishableProductQuerySet(ProductQuerySet):defget_active_products(self):returnself.filter(is_perished=False)classBrokenProductQuerySet(ProductQuerySet):defget_active_products(self):returnself.filter(repaired=True)

但是在这个实现中ProductQuerySet将返回所有产品,包括保存的产品 当PerishableProductis_perished等于True,而BrokenProductrepaired等于False

溶液

这个库允许您创建考虑到queryset中所有条件的多态queryset。 层次结构(注意,查询函数属于类,而不是类实例,用作@classmethod装饰器):

frompolymorphic_querysetimportQueryable,queryfromdjango.dbimportmodelsclassProductQuerySet(Queryable,models.QuerySet):model_name="Product"@query()defget_active_products(cls):returnquery.all()classPerishableProductQuerySet(ProductQuerySet):model_name="PerishableProduct"@query()defget_active_products(cls):returnmodels.Q(is_perished=False)classBrokenProductQuerySet(ProductQuerySet):model_name="BrokenProduct"@query()defget_active_products(cls):returnmodels.Q(repaired=True)

此实现基于指定的模型名在不同的查询集之间分离查询条件。 ProductQuerySet.get_active_products将返回任何保存为Product的产品, 如果is_perishedfalseBrokenProductrepairedtrue则保存为PerishableProduct的产品。 queryset仍将返回Product实例。

您可以使用django多态库来返回派生类的实例。

现在,您可以将这些查询集用作模型管理器:

fromdjango.dbimportmodelsclassProduct(models.Model):objects=ProductQuerySet.as_manager()classPerishableProduct(Product):objects=PerishableProductQuerySet.as_manager()classBrokenProduct(Product):objects=BrokenProductQuerySet.as_manager()active_products=Product.objects.get_active_products()

要在查询集中使用基类的条件,可以调用用query修饰的方法的conditions函数:

frompolymorphic_querysetimportQueryable,queryfromdjango.dbimportmodelsimportdatetimeclassProductQuerySet(Queryable,models.QuerySet):model_name="Product"@query()defget_new_products(cls):returnmodels.Q(date_created__gte=datetime.datetime.now()-datetime.timedelta(weeks=1))classPerishableProductQuerySet(ProductQuerySet):model_name="PerishableProduct"@query()defget_new_products(cls):returnsuper().get_new_products.conditions()&models.Q(date_perished__lt=datetime.datetime.now())

在本例中,get_new_products将返回不到一周前创建的任何Product,或者 PerishableProduct如果它是一周前创建的,今天不会消亡。

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

推荐PyPI第三方库


热门话题
java Spring AOP:在方法之间交换信息   数组Java将字符串转换为字符[]   堆内存java。lang.OutOfMemoryError:PermGen space+java   安卓 Java。lang.ClassCastException:无法将活动强制转换到接口   java尝试使用气泡排序将随机整数数组从最大到最小排序   线程“main”java中的indexoutofboundsexception异常。lang.ArrayIndexOutofBounds异常:发电机处为3。main(Generator.java:35)   java“宽大”有什么用?   java SimpleCaptcha NoSuchMethodError   java在哪里部署Web服务的jar依赖项?   Java8获取列表中连续数字的函数方法   java为什么JWT令牌不安全?   java Uber API:在请求或发出令牌时指定多个作用域会返回无效的请求参数   java如何使用映射器从包含多个引用单元的JSON字符串中获取对象列表?   java警告匿名子类(?)没有串行版本   Jackson 2.9.0中的java JsonGenerationException。pr1   java试图打印多个catch语句   java如何创建一个sql表并获得每个唯一字段的平均价格?   java为什么SetMinimumSize设置最小高度而不是宽度?   java与使用POI合并的混淆   java在Xpath中使用“AND”和“normalizespace”时在不同浏览器中遇到不同的错误