Django 模型:是否可以使用管理器为特定字段强制 filter/get 上的 icontains?
Django models: is it possible to force icontains on filter/get for specific field using a manager?
假设我有一个带有类似于此字符串字段的模型
class Product(models.Model):
upc = models.CharField(max_length=12, blank=False, null=False)
是否可以构建一个模型管理器或类似的东西,每次我使用 Product.objects.get
/Product.objects.filter
它都会覆盖默认查找以强制 search/filter 表现得像我一样使用 icontains
?
如:
Product.objects.get(upc="012345678902")
Product.objects.filter(upc="012345678902")
默认情况下的行为如下:
Product.objects.get(upc__icontains="012345678902")
Product.objects.filter(upc__icontains="012345678902")
您可以自定义查询管理器或查询集,并覆盖 get/filter 方法。下面的演示可以告诉您如何自定义查询管理器实现强制图标。
from django.db import models
class ForceIContainsManager(models.Manager):
force_icontains_fields = None
def __init__(self, *args, **kwargs) -> None:
if "force_icontains_fields" in kwargs:
self.force_icontains_fields = kwargs.pop("force_icontains_fields")
super(ForceIContainsManager, self).__init__(*args, **kwargs)
def get(self, *args, **kwargs):
kwargs = self._force_icontains(**kwargs)
return super(ForceIContainsManager, self).get(*args, **kwargs)
def filter(self, *args, **kwargs):
kwargs = self._force_icontains(**kwargs)
return super(ForceIContainsManager, self).filter(*args, **kwargs)
def _force_icontains(self, **kwargs):
"""
replace field in force_icontains_fields to icontains style
"""
if not self.force_icontains_fields:
return kwargs
for field in self.force_icontains_fields:
if field in kwargs:
v = kwargs.pop(field)
new_field_name = '%s__icontains' % field
kwargs[new_field_name] = v
return kwargs
class YourModel(models.Model):
# define a another manager, YourModel.manager will force icontains on certain fields
manager = ForceIContainsManager(
force_icontains_fields=["field1", "field2"])
# if you want use YourModel.objects, you should uncomment below
# objects = ForceIContainsManager(force_icontains_fields=["field1", "field2"])
pass
# check sql
print(YourModel.manager.filter(field1='test').query)
更多定制可以看https://sodocumentation.net/django/topic/1400/custom-managers-and-querysets
QueryManager 代理了QuerySet 中的所有方法BaseManager.from_queryset
,选择一个就够了。
假设我有一个带有类似于此字符串字段的模型
class Product(models.Model):
upc = models.CharField(max_length=12, blank=False, null=False)
是否可以构建一个模型管理器或类似的东西,每次我使用 Product.objects.get
/Product.objects.filter
它都会覆盖默认查找以强制 search/filter 表现得像我一样使用 icontains
?
如:
Product.objects.get(upc="012345678902")
Product.objects.filter(upc="012345678902")
默认情况下的行为如下:
Product.objects.get(upc__icontains="012345678902")
Product.objects.filter(upc__icontains="012345678902")
您可以自定义查询管理器或查询集,并覆盖 get/filter 方法。下面的演示可以告诉您如何自定义查询管理器实现强制图标。
from django.db import models
class ForceIContainsManager(models.Manager):
force_icontains_fields = None
def __init__(self, *args, **kwargs) -> None:
if "force_icontains_fields" in kwargs:
self.force_icontains_fields = kwargs.pop("force_icontains_fields")
super(ForceIContainsManager, self).__init__(*args, **kwargs)
def get(self, *args, **kwargs):
kwargs = self._force_icontains(**kwargs)
return super(ForceIContainsManager, self).get(*args, **kwargs)
def filter(self, *args, **kwargs):
kwargs = self._force_icontains(**kwargs)
return super(ForceIContainsManager, self).filter(*args, **kwargs)
def _force_icontains(self, **kwargs):
"""
replace field in force_icontains_fields to icontains style
"""
if not self.force_icontains_fields:
return kwargs
for field in self.force_icontains_fields:
if field in kwargs:
v = kwargs.pop(field)
new_field_name = '%s__icontains' % field
kwargs[new_field_name] = v
return kwargs
class YourModel(models.Model):
# define a another manager, YourModel.manager will force icontains on certain fields
manager = ForceIContainsManager(
force_icontains_fields=["field1", "field2"])
# if you want use YourModel.objects, you should uncomment below
# objects = ForceIContainsManager(force_icontains_fields=["field1", "field2"])
pass
# check sql
print(YourModel.manager.filter(field1='test').query)
更多定制可以看https://sodocumentation.net/django/topic/1400/custom-managers-and-querysets
QueryManager 代理了QuerySet 中的所有方法BaseManager.from_queryset
,选择一个就够了。