class Jornal(models.Model):
url = models.URLField(unique = True,blank=True)
name = models.CharField(max_length=100)
def __str__(self):
return self.name
@property
def domain(self):
return urlparse(self.url).netloc
我如何通过其域获取Jornal对象?我正在外壳中尝试此操作:
domain = "www.example.com"
obj = Jornal.objects.get_domain(domain)
然后这个:
domain = "www.example.com"
obj = Jornal.objects(domain = domain)
但是没有办法。
编辑我正在尝试使用get方法,因为在没有找到它的情况下,我需要DidNotExist。
最佳答案
由于该属性是在运行时存储的,因此,如果我们将该属性视为黑匣子,则只能通过在Python级别进行过滤来做到这一点。因此,例如列表理解:
domain = "www.example.com"
all_example_domain = [j for j in Journal.objects.all() if j.domain == domain]
通常,我们不能反转函数,因此我们不能为此在数据库级别使用过滤。
然而,在这里,我们现在有了一些额外的东西:
domain
是URL的子字符串。因此,我们可以通过在数据库级别进行一些过滤来增强过滤过程:domain = "www.example.com"
all_example_domain = [j for j in Journal.objects.filter(url__icontains=domain)
if j.domain == domain]
因此,这里我们已经过滤掉了
Journal
对象,其中url
不包含请求的domain
。从技术上讲,其中仍然可能存在错误(例如,带有www.example.com.com
的url)。因此,我们最好使用j.domain == domain
进行第二次过滤。如果没有这样的对象,则列表将为空;如果有多个,则列表将包含两个或多个项目。
我们可以使用它编写一个函数,该函数将进行适当的过滤,并在找不到这样的对象或多个对象的情况下引发错误。例如:
从itertools导入islice
def property_get(query_set, **kwargs):
results = list(islice((j for j in qs
if all(getattr(j, k) == v for k, v in kwargs.items())),
2))
if results:
if len(results) > 1:
raise MultipleObjectsReturned
return results[0]
else:
raise ObjectDoesNotExist
因此,我们可以使用
property_get(Journal.objects.all(), domain=domain)
进行查询,它将引发ObjectDoesNotExist
或MultiObjectsReturned
异常。但这效率很低。通常,如果您经常查询属性,将属性存储在数据库以及字段中而不使用属性,则更好。