0 Tage Serie
python / intermediate
Snippet

Django Benutzerdefinierter Model Manager und QuerySet Methoden

Dieses Muster zeigt wie man wiederverwendbare QuerySet-Methoden durch Verketten über einen benutzerdefinierten Manager erstellt. Die PublishedQuerySet-Klasse kapselt Abfragelogik in wiederverwendbaren Methoden die verkettet werden können. Der ArticleManager delegiert an dieses QuerySet und bietet eine saubere API. Dieser Ansatz hält Abfragelogik modular und testbar.

snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from django.db import models
class PublishedQuerySet(models.QuerySet):
def published(self):
return self.filter(status='published')
def in_date_range(self, start, end):
return self.filter(published_date__range=[start, end])
def by_author(self, author):
return self.filter(author=author)
def with_min_views(self, min_views):
return self.filter(view_count__gte=min_views)
class ArticleManager(models.Manager):
def get_queryset(self):
return PublishedQuerySet(self.model, using=self._db)
def published(self):
return self.get_queryset().published()
def with_min_views(self, min_views):
return self.get_queryset().with_min_views(min_views)
class Article(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=20, default='draft')
published_date = models.DateTimeField(null=True)
view_count = models.IntegerField(default=0)
content = models.TextField()
objects = ArticleManager()
class Meta:
ordering = ['-published_date']
django
Erklärung
1
class PublishedQuerySet(models.QuerySet):
Definiere benutzerdefinierte QuerySet-Klasse erbend von models.QuerySet
2
def published(self):
Filtermethode die nur veröffentlichte Artikel zurückgibt
3
return self.filter(status='published')
Filter auf QuerySet verketten und zurückgeben
4
def in_date_range(self, start, end):
Datumsbereich-Filtermethode mit Start- und Endparametern
5
def by_author(self, author):
Methode um Artikel nach spezifischer Autoreninstanz zu filtern
6
class ArticleManager(models.Manager):
Benutzerdefinierte Manager-Klasse erbend von models.Manager
7
return PublishedQuerySet(self.model, using=self._db)
Überschreibe get_queryset um benutzerdefiniertes QuerySet mit korrekter Datenbank-Routing zurückzugeben
8
objects = ArticleManager()
Weise benutzerdefinierten Manager als Standard-Manager für das Modell zu