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

Django自定义管理器关键字参数,django,python-2.7,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 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\u queryset
不接受额外的参数。那么,我应该重写什么方法,或者我应该如何去做呢

编辑:

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

我遇到的问题是当试图通过解析链接来添加站点时
http://example.com
http://www.example.com
我们创建了两个不同的站点,这不是我们想要的结果。因此,我的解决方案是将一个空子域默认为
www

问题是如果以后解析
http://example.com
并尝试让站点查看它是否存在,它将返回它不存在的结果@mad_wombat说你不应该返回用户没有要求的东西,但是如果子域永远不会是空的,如果它是空的,那么它实际上应该是
www
,那么你为什么不返回呢?我想我可以在每次get调用之前执行卫生检查,或者执行自定义方法,这似乎是在添加新的内容,而不是让
get()
调用按照本例中的方式工作


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

当然,您可以覆盖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) def get_站点(域、子域='www'): 返回Site.objects.get(域=域,子域=子域) 或者,您可以将其设置为管理器方法,而不是独立函数,并像这样调用它

Site.objects.get_site(domain, subdomain) Site.objects.get_站点(域、子域)
但是,如果其他人使用您的代码,他们不会期望get()或filter()执行任何神奇的替换。

当然,您可以覆盖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) def get_站点(域、子域='www'): 返回Site.objects.get(域=域,子域=子域) 或者,您可以将其设置为管理器方法,而不是独立函数,并像这样调用它

Site.objects.get_site(domain, subdomain) Site.objects.get_站点(域、子域)
但是,如果其他人正在使用您的代码,他们就不会期望get()或filter()执行任何神奇的替换。

@mad_wombat非常合适-您不希望get/filter调用中出现任何“神奇”现象。为了补充他的答案,你可能需要问自己为什么要做这项工作。如果“Site”对象需要子域,您可能希望重写“save”方法(或“clean”方法之一)以强制执行此要求。@mad_wombat我编辑了我的问题。我理解你为什么说一般来说你不应该归还用户没有要求的东西。但是,我不知道为什么如果有人请求一个不可能的空值,那么失败比简单地返回空值已更改为的默认值要好。对于您正在寻找的实际答案,实际上可以在manager中重写get()。查看您的编辑,您不必确保save()中的唯一性,您所需要的只是Meta中的“unique_together”字段。创建自定义方法可能比透明重写预期的更好behavior@MadWombat谢谢你们在一起的独特经历。我回去查看了我的代码。我想我经常打电话。实际上我只用过一次。其他一切都是凭身份证,所以现在我听从你的建议。谢谢。@mad_袋熊很好-你不希望在get/filter调用中出现任何“魔力”。为了补充他的答案,你可能需要问自己为什么要做这项工作。如果“Site”对象需要子域,您可能希望重写“save”方法(或“clean”方法之一)以强制执行此要求。@mad_wombat我编辑了我的问题。我理解你为什么说一般来说你不应该归还用户没有要求的东西。但是,我不知道为什么如果有人请求一个不可能的空值,那么失败比简单地返回空值已更改为的默认值要好。对于您正在寻找的实际答案,实际上可以在manager中重写get()。查看您的编辑,您不必确保save()中的唯一性,您只需要Met中的“unique_together”字段