python - Django 如何按字段覆盖模型匹配

标签 python django orm model

我正在使用 django 1.5.5 和 python 2.6

我有这个模型

class Site(models.Model):
    url = models.CharField(max_length = 512)

我想自定义模型,以便 url 具有“www”前缀的网站和不具有“www”前缀的网站将返回相同的对象。
因此,如果我有一个网址为 url=' http://foo.com 的网站' 以下所有内容都将返回相同的对象

mysite = Site.objects.get(url__iexact='http://foo.com')
mysite = Site.objects.get(url__iexact='http://www.foo.com')
mysite = Site.objects.filter(url__iexact='http://foo.com')
mysite = Site.objects.filter(url__iexact='http://www.foo.com')

我正在考虑制作一个类似的类方法。

@classmethod
def get_site(cls,url):
    # search for site with url = url
    if url.startswith('http://www'):
         # search without www
    else:
         # search with www
    return site

但我确信有更好的方法可以继续使用 objects.getobjects.filter

更新:

按照 Gonzalo Delgado 的建议,我制作了一个自定义模型管理器

这是我的代码

def url_variants(url):
prefixes = ['http://www.','https://www.','http://','https://',]  # order must be from longest to shortest
for prefix in prefixes:
    if url.startswith(prefix):
        url = url[len(prefix):]
        break
return [ prefix+url for prefix in prefixes]

class SiteManager(models.Manager):
    def filter(self, *args, **kwargs):            
        if 'url' in kwargs:
            variants = url_variants(url)
            # in order to chain '__in' and '__iexact' Q is needed
            q_list = [Q(url__iexact=n) for n in variants]
            q_list = reduce(lambda a, b: a | b, q_list)
            args =  (q_list,) + args            
            kwargs.pop("url", None) # remove original Field lookups
        return super(SiteManager, self).filter(*args, **kwargs)

这很好用,现在唯一的问题是,如果我使用任何类型的字段查找,那么它不会使用新逻辑。
所以任何类型的 url__inurl__contains 等都不起作用。
我确信有比在 django 中实现每个可用的归档查找更好的方法。

最佳答案

您需要创建一个 custom manager并扩展 get 和过滤 methods:

class SiteManager(models.Manager):
    def get(self, *args, **kwargs):
        if 'url' in kwargs:
            # handle 'www' prefix here and update kwargs['url'] accordingly
        return super(SiteManager, self).get(*args, **kwargs)


    def filter(self, *args, **kwargs):
        if 'url' in kwargs:
            # handle 'www' prefix here and update kwargs['url'] accordingly
        return super(SiteManager, self).filter(*args, **kwargs)

class Site(models.Model):
    url = models.CharField(max_length = 512)

    objects = SiteManager()

关于python - Django 如何按字段覆盖模型匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20610810/

相关文章:

python - 如何使Keras网络不输出全1

python - 如何以列表格式获取 spotipy 播放列表结果

python - 从 python struct.pack (big-endian) 转换为整数列表

python - Django select_related 不执行任何操作

java - 我可以将 Realm 用作 postgres ORM 吗?

python - 在 python 中指定日期时间所在的时区

Django 模板,如果标记基于当前 URL 值

python - 删除 PIP 中所有已失效依赖者的包

android - ReActiveAndroid - 未找到引用的数据库信息

python - SQLAlchemy 映射以列出相关对象