有没有办法检查相关对象是否已经被获取? [英] Is there a way to check whether a related object is already fetched?
问题描述
我希望能够使用 select_related
或 prefetch_related
,以便我可以相应地序列化数据。下面是一个示例:
I would like to be able to check if a related object has already been fetched by using either select_related
or prefetch_related
, so that I can serialize the data accordingly. Here is an example:
class Address(models.Model):
street = models.CharField(max_length=100)
zip = models.CharField(max_length=10)
class Person(models.Model):
name = models.CharField(max_length=20)
address = models.ForeignKey(Address)
def serialize_address(address):
return {
"id": address.id,
"street": address.street,
"zip": address.zip
}
def serialize_person(person):
result = {
"id": person.id,
"name": person.name
}
if is_fetched(person.address):
result["address"] = serialize_address(person.address)
else:
result["address"] = None
######
person_a = Person.objects.select_related("address").get(id=1)
person_b = Person.objects.get(id=2)
serialize_person(person_a) #should be object with id, name and address
serialize_person(person_b) #should be object with only id and name
在此示例中,函数 is_fetched
是我要的东西。我想确定person对象是否已经有一个解析地址,并且只有在有解析地址的情况下,也应该对其进行序列化。
In this example, the function is_fetched
is what I am looking for. I would like to determine if the person object already has a resolves address and only if it has, it should be serialized as well. But if it doesn't, no further database query should be executed.
那么在Django中有没有办法做到这一点?
So is there a way to achieve this in Django?
推荐答案
如果已获取 address
关系,则Person对象将具有称为<$ c的填充属性。 $ c> _address_cache ;您可以检查一下。
If the address
relation has been fetched, then the Person object will have a populated attribute called _address_cache
; you can check this.
def is_fetched(obj, relation_name):
cache_name = '_{}_cache'.format(relation_name)
return getattr(obj, cache_name, False)
请注意需要使用对象和关系名称来调用它:
Note you'd need to call this with the object and the name of the relation:
is_fetched(person, 'address')
因为执行 person.address
会立即触发获取。
since doing person.address
would trigger the fetch immediately.
编辑反向或多对多关系只能通过 prefetch_related
获取;填充单个属性 _prefetched_objects_cache
,该属性是列表的字典,其中键是相关模型的名称。例如,如果您这样做:
Edit reverse or many-to-many relations can only be fetched by prefetch_related
; that populates a single attribute, _prefetched_objects_cache
, which is a dict of lists where the key is the name of the related model. Eg if you do:
addresses = Address.objects.prefetch_related('person_set')
,那么地址
中的每个项目都会具有 _prefetched_objects_cache
字典包含一个个人
键。
then each item in addresses
will have a _prefetched_objects_cache
dict containing a "person'
key.
请注意,这两个都是下划线属性,这意味着它们是私有API的一部分;您可以自由使用它们,但Django也可以在将来的版本中自由更改它们。
Note, both of these are single-underscore attributes which means they are part of the private API; you're free to use them, but Django is also free to change them in future releases.
这篇关于有没有办法检查相关对象是否已经被获取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!