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
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 modelsclass 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