Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to check whether a related object is already fetched?

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

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.

So is there a way to achieve this in Django?

like image 313
basilikum Avatar asked Apr 04 '16 12:04

basilikum


1 Answers

Since Django 2.0 you can easily check for all fetched relation by:

obj._state.fields_cache

ModelStateFieldsCacheDescriptor is responsible for storing your cached relations.

>>> Person.objects.first()._state.fields_cache
{}
>>> Person.objects.select_related('address').first()._state.fields_cache
{'address': <Address: Your Address>}
like image 86
vishes_shell Avatar answered Oct 19 '22 04:10

vishes_shell