pythondjangodjango-modelsdjango-prefetch-related

prefetch_related within model method


So I have a Django model which is a foreign key for several other models. I want to add a method to my model and see if my instance of the model actually has any related objects. Two questions:

  1. I'd like to do this with one query, but I'm unsure how to use prefetch_related with self. How do I do this?

  2. Is there a way to just return True or False if a related model exists? For example, should I just use first? (I seem to recall there being a "correct" way to do this, but it's been a while, and I may be remembering flask.)

Code example:

from django.db import models

class Person(models.Model):
  # <fields>

  def has_device(self):
    # ***prefetch related phones and laptops***
    if self.phone_set.first() or self.laptop_set.first():
      return True
    return False

class Laptop(models.Model):
  owner = models.ForeignKey(Person)
  # <fields>


class Phone(models.Model):
  owner = models.ForeignKey(Person)
  # <fields>

Solution

  • Answers to your questions in reverse order:

    1. The canonical way to do this is to use the .exists() query:
    return self.phone_set.exists() or self.laptop_set.exists()
    
    1. There is no real point trying to do this in one query, as they are different tables. That being said, you can try the prefetch_related_objects helper:
    from django.db.models import prefetch_related_objects
    ...
        def has_device(self):
            prefetch_related_objects([self], "phone_set", "laptop_set")
            return self.phone_set.exists() or self.laptop_set.exists()