Django自定义管理器关键字参数

时间:2016-03-28 18:46:25

标签: django python-2.7

我有以下型号。

class Site(models.Model):
   domain = models.CharField(max_length=255, blank=True)
   subdomain = models.CharField(max_length=255, blank=True)

如果某个网站没有子域名,我希望它默认为www。这很容易做到。但是,如果在没有子域的情况下调用Site.objects.get(domain='example.com'),我想将子域设置为www

我尝试过这样的事情:

class SitesManager(models.Manager):
    def get_queryset(self, *args, **kwargs):
        if 'domain' in kwargs.keys() and 'subdomain' not in kwargs.keys():
            kwargs['subdomain'] = 'www'
        qs = super(SitesManager, self).get_queryset(args, kwargs)
        return qs

class Site(models.Model):
   domain = models.CharField(max_length=255, blank=True)
   subdomain = models.CharField(max_length=255, blank=True)
   objects = SitesManager()

但显然get_queryset没有采取其他参数。那么我应该采用什么方法来覆盖或者我将如何实现呢?

修改

目标是只有一个网站具有相同的域和子域。但是,您可能有多个站点具有相同的域,但不同的子域,反之亦然。因此,您无法使域或子域唯一,但这很容易在save方法中处理,因此每个域子域组合都是唯一的。

我遇到的问题是,在尝试通过解析链接http://example.comhttp://www.example.com来添加网站时,我们会导致两个不同的网站,而这些网站并非所需的结果。所以我的解决方案是将空子域默认为www

问题在于,如果您稍后解析http://example.com并尝试让网站查看它是否存在,则会返回它不会。 @mad_wombat说你不应该返回用户没有要求的东西,但如果子域永远不会是空的,如果它是空的,它实际上应该是www那么为什么不会你回来了吗?我想我可以在每次接听电话之前进行卫生检查,或者做一个自定义方法,这似乎是我添加一些新的东西,而不是让get()呼叫以它应该的方式工作这个例子。

更一般地说,如果数据库字段具有默认值,那么它不会让您将空值粘贴到该字段中,因此不让用户请求更有意义该字段中的空值比告诉它们没有结果?

1 个答案:

答案 0 :(得分:0)

当然,您可以覆盖get()和filter(),这将为您提供或多或少的结果。但你可能不想这样做。 QuerySet方法是RDBMS的python API,filter()和get()调用是SQL语句的python表示。人们在与数据库交谈时通常会指望的一件事是它会返回他们要求的东西。你在这里尝试做的是透明地返回用户没有要求的东西。如果您是唯一的用户,则无人阻止您检查您的子域是否为空并默认情况下获取“www”

def get_site(domain, subdomain='www'):
    return Site.objects.get(domain=domain, subdomain=subdomain)

或者您可以将其设为管理员方法而不是独立功能,并将其称为

Site.objects.get_site(domain, subdomain)

但是如果其他人会使用你的代码,他们就不会期望get()或filter()做任何魔术替换。