.. _tag_model: .. index:: single: Many-to-Many-Beziehung single: Tag 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. .. image:: /images/uml_class_4.png .. code-block:: python 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. .. code-block:: bash 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: .. code-block:: python 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. .. code-block:: python 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. .. code-block:: bash 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. .. code-block:: bash >> 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:** * ``_