DJANGO模型:是否有可能使用经理使用特定字段上的特定字段来强制IContains?

发布于 2025-01-28 21:37:53 字数 686 浏览 2 评论 0原文

假设我有一个与此类似的字符串字段的模型,

class Product(models.Model):
    upc = models.CharField(max_length=12, blank=False, null=False)

这是可以构建模型管理器或类似的模型,而每次我使用product.objects.get/product.objects.filter时它覆盖默认查找,以强迫搜索/过滤器的行为,就像我使用过icontains一样?

如下:

Product.objects.get(upc="012345678902")
Product.objects.filter(upc="012345678902")

默认情况下的行为会如下:

Product.objects.get(upc__icontains="012345678902")
Product.objects.filter(upc__icontains="012345678902")

Let's say I have a model with a string field similar to this

class Product(models.Model):
    upc = models.CharField(max_length=12, blank=False, null=False)

Is it possible to build a model manager or something similar where every time I use Product.objects.get/Product.objects.filter it overrides the default lookup to force the search/filter to behave like I had used icontains?

As in:

Product.objects.get(upc="012345678902")
Product.objects.filter(upc="012345678902")

By default would behave like:

Product.objects.get(upc__icontains="012345678902")
Product.objects.filter(upc__icontains="012345678902")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅忆流年 2025-02-04 21:37:53

您可以自定义查询管理器或QuerySet,并覆盖GET/过滤器方法。下面的演示可以告诉您如何自定义查询管理器实施强制IContains。

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:/ 1400/custom-managers and QuerySets

QueryManager在QuerySet中使用baseManager.from_queryset的所有方法代理所有方法,选择一个已经足够了。

You can custom a query manager or queryset, and override the get/filter method. The demo below can tell you how to custom a query manager implements force icontains.

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)

More customize can see https://sodocumentation.net/django/topic/1400/custom-managers-and-querysets

QueryManager has proxy all method in QuerySet by BaseManager.from_queryset, choose one is enought.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文