python / expert
Snippet
Django ContentType-Framework für generische Beziehungen
Djangos ContentType-Framework ermöglicht generische Beziehungen und erlaubt einem einzelnen Comment-Modell, sich an jedes andere Modell anzuhängen, ohne separate Fremdschlüssel zu erstellen. Dies ist ideal für den Aufbau wiederverwendbarer Komponenten wie Kommentare, Tags oder Likes. Die GenericRelation an den Zielmodellen ermöglicht umgekehrte Lookups, während der zusammengesetzte Index auf content_type und object_id effizientes Abfragen gewährleistet.
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
from django.db import modelsfrom django.contrib.contenttypes.models import ContentTypefrom django.contrib.contenttypes.fields import GenericForeignKey, GenericRelationclass Comment(models.Model):content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)object_id = models.PositiveIntegerField()content_object = GenericForeignKey('content_type', 'object_id')text = models.TextField()created_at = models.DateTimeField(auto_now_add=True)class Meta:indexes = [models.Index(fields=['content_type', 'object_id']),]class Article(models.Model):title = models.CharField(max_length=200)body = models.TextField()comments = GenericRelation(Comment, related_query_name='articles')class Product(models.Model):name = models.CharField(max_length=200)price = models.DecimalField(max_digits=10, decimal_places=2)comments = GenericRelation(Comment, related_query_name='products')# Usage exampledef get_recent_comments(obj, limit=5):content_type = ContentType.objects.get_for_model(obj)return Comment.objects.filter(content_type=content_type,object_id=obj.pk).order_by('-created_at')[:limit]
django
Erklärung
1
content_type = models.ForeignKey(ContentType, ...)
Speichert, welche Modellklasse der Kommentar zugeordnet ist
2
object_id = models.PositiveIntegerField()
Speichert den Primärschlüssel des zugehörigen Objekts
3
GenericForeignKey('content_type', 'object_id')
Löst zur Laufzeit dynamisch zum tatsächlichen zugehörigen Objekt auf
4
GenericRelation(Comment, related_query_name='articles')
Ermöglicht Article.comments.all() und Comment.objects.filter(articles=article)
5
ContentType.objects.get_for_model(obj)
Ruft die ContentType-Instanz für ein beliebiges Django-Modell dynamisch ab
6
models.Index(fields=['content_type', 'object_id'])
Zusammengesetzter Index für schnelle Lookups beim Filtern nach Inhaltstyp und ID