Django modele, Relacje między modelami - 108:

108. Jak zoptymizować wczytywanie danych przez zapytania ORM (w zależności od relacji)? Jakie są różnice w: 'select_related' i 'prefetch_related'?
Odpowiedź:
  • Użycie select_related dla relacji: One-To-One i One-To-Many:
  • # Bez użycia 'select_related', tylko 'related_name' (dwa zapytania sql):
    first_autor = Author.objects.first()
    books = first_autor.books.all()
    
    # Używając 'select_related' (jedno zapytanie sql):
    books = first_autor.books.select_related('author').all()
    

  • Użycie prefetch_related dla relacji Many-To-Many:
  • 
    class Book(models.Model):
        title = models.CharField(max_length=100, unique=True)
        author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="books")
        category = models.ManyToManyField(BookCategory, related_name="books")
    
    books = Book.objects.filter(author=first_autor).prefetch_related('category')
    
    Jak działa prefetch_related?
    • Wykonuje zapytanie główne (np. dla książek).
    • Wykonuje osobne zapytanie dla relacji Many-to-Many (np. dla kategorii książek), aby pobrać powiązane obiekty.
    • Łączy wyniki w Pythonie, co oznacza, że Django nie łączy tabel w zapytaniu SQL, ale łączy obiekty w pamięci (na poziomie aplikacji).