Many to Many Beziehung
Bisher hatten wir uns auschließlich mit 1-N Beziehungen befasst, genauergesagt
mit dem ForeignKey
- Feld des Django-Models, der sogenannten One-to-Many
Beziehung. Nun wollen wir uns mit einer
weiteren Beziehung befassen, nämlich der M-N Beziehung, auch bekannt als
Many-to-Many
Beziehung.
Eine M-N Beziehung zeichnet sich in relationalen Datenbanken dadurch aus, dass
sie nur mithilfe einer Zwischentabelle abgebildet werden kann. Django ist hier
aber extrem zuvorkommend. Durch das Anlegen eines ManytoMany
Felds wird von
Django diese Tabelle generiert, wir haben damit weiter nichts zu tun.
Das Tag Modell
Wir wollen für unsere Events die Möglichkeit haben, sie mit diversen Begriffen zu taggen, zum Beispiel Freizeit oder Weekend Fun. Jeder Tag kann mehreren Events zugeordnet werden und jeder Event hat mehere Tags.
Hier noch kurz das UML-Modell unserer Anwendung und die neue Tag-Klasse, wie sie in Verbindung zum Event steht.
class Tag(models.Model):
description = models.TextField(blank=True, null=True)
icon = models.CharField(max_length=19)
name = models.CharField(
max_length=99,
unique=True,
)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
def __str__(self):
return self.name
Wenn wir die nötigen Migrationen durchführen, wird jetzt ein Tag-Model angelegt.
python manage.py makemigrations events
python manage.py migrate events
Um das Model in der Admin verfügbar zu machen, fügen wir noch diesen Code in
die event_manager/events/admin.py
ein:
from .models import Category, Event, Tag
# registrieren das Tag-Model
admin.site.register(Tag)
Wenn wir uns jetzt auf der Adminoberfläche per Browser einloggen, sollten wir das Tag-Model jetzt sehen können. Probeweise legen wir ein paar Tags an.
MISSING: IMAGE
Das Event Modell
Nun müssen wir nur noch unser Event-Model unter
event_manager/events/models.py
anpassen.
Im Event-Model definieren wir mit einem ManyToMany
- Feld die M-N
Beziehung. Auch hier nutzen wir den related_name
, wir wir das schon beim
ForeignKey-Feld gemacht hatten.
class Event(DateMixin):
[..]
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="events")
# das hier eintragen:
tags = models.ManyToManyField(Tag, related_name="events", blank=True)
class Meta:
ordering = ["name"]
[..]
Mit blank=True
sagen wir, dass Tags optional sind.
Nun muss die App nochmal migriert werden.
python manage.py makemigrations events
python manage.py migrate events
Wenn wir uns jetzt auf der Adminoberfläche per Browser einloggen, sollten wir den Events nun die vorhin erstellten Tags zurordnen können.
Hier einige Beispiele, wie man mit diesen beiden Models arbeiten würde.
>> from events.models import Event, Tag
>> # Zwei Tags anlegen
>> tag1 = Tag.objects.create(name="Summer and Sun")
>> tag2 = Tag.objects.create(name="City")
>> # einen Event selektieren
>> event1 = Event.objects.all().first()
>> # diesem Event zwei Tags zurordnen mit add
>> event1.tags.add(tag1)
>> event1.tags.add(tag2)
>> # Alle Events auflisten, die tag2 zugeordnet sind
>> tag2.events.all()
>> # Alle Tags eines Events auflisten
>> event1.tags.all()
MISSING: IMAGE
Weitere Beispiele zur ManyToMany-Beziehung findet sich in der Django-Doku: * https://docs.djangoproject.com/en/stable/topics/db/examples/many_to_many/