python / expert
Snippet
Django ContentTypes Framework für Generic Relations
Django's ContentTypes Framework ermöglicht Generic Relationships, die es einem einzigen Model erlauben, beliebige andere Models im System zu referenzieren. Dies ist ideal für Tagging-Systeme, Kommentare oder jedes Szenario, in dem flexible Foreign-Key-Beziehungen ohne mehrere Foreign-Key-Spalten benötigt werden. Der GenericForeignKey arbeitet mit zwei Spalten: content_type speichert den Model-Typ und object_id speichert den Primary Key des referenzierten Objekts.
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
from django.db import modelsfrom django.contrib.contenttypes.models import ContentTypefrom django.contrib.contenttypes.fields import GenericForeignKey, GenericRelationclass TaggedItem(models.Model):tag = models.CharField(max_length=100)content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)object_id = models.PositiveIntegerField()content_object = GenericForeignKey('content_type', 'object_id')class Meta:indexes = [models.Index(fields=['content_type', 'object_id']),]class Article(models.Model):title = models.CharField(max_length=200)tags = GenericRelation(TaggedItem, related_query_name='articles')class Product(models.Model):name = models.CharField(max_length=200)tags = GenericRelation(TaggedItem)def get_objects_by_tag(tag_name):content_type = ContentType.objects.get_for_model(Article)return TaggedItem.objects.filter(tag=tag_name,content_type=content_type).select_related('content_object')def get_all_tags_for_object(obj):return obj.tags.all() if hasattr(obj, 'tags') else []
django
Erklärung
1
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
Importiert Generic-Relationship-Feldklassen vom ContentTypes-App
2
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
Speichert Referenz zum ContentType-Datensatz des Ziel-Models
3
object_id = models.PositiveIntegerField()
Speichert den PK des verknüpften Objekts (unterstützt jeden Integer-PK)
4
GenericRelation(TaggedItem, related_query_name='articles')
Erstellt Reverse-Accessor für Article.tags.all() Abfragen
5
ContentType.objects.get_for_model(Article)
Ruft die ContentType-Instanz für das Article Model dynamisch ab
6
models.Index(fields=['content_type', 'object_id'])
Zusammengesetzter Index optimiert GenericForeignKey-Lookups