image
24 lutego 2023

Praca z danymi relacyjnymi w Django: ForeignKey, OneToOneField i ManyToManyField

24 lutego 2023

W tym wpisie skupimy się na kluczowym aspekcie tworzenia aplikacji internetowyc - pracy z danymi relacyjnymi. Django oferuje potężne narzędzia do zarządzania takimi danymi, co ułatwia modelowanie złożonych struktur danych i zależności między nimi.

 

Dane relacyjne odnoszą się do struktury danych, w której dane są zorganizowane w formie tabel (zwanych modelami w Django), a relacje między danymi są reprezentowane za pomocą powiązań między tymi tabelami. Django obsługuje trzy główne typy relacji: "ForeignKey", "OneToOneField"  i "ManyToManyField".

 

W tym wpisie zbadamy te trzy typy relacji, zrozumiemy jak je implementować w modelach Django i dowiemy się, jak manipulować danymi relacyjnymi za pomocą ORM Django. Przedstawimy to na przykładzie modelowania zależności między krajami, ich stolicami i innymi miastami. Zaczynajmy!

 

 

Rodzaje relacji między modelami

 

W Django relacje między modelami są reprezentowane za pomocą specjalnych pól, które definiują typ relacji między encjami. Mamy do czynienia z trzema głównymi typami relacji: jeden do wielu, jeden do jednego i wiele do wielu. Te relacje są reprezentowane w Django odpowiednio za pomocą ForeignKey, OneToOneField i ManyToManyField.

 

ForeignKey

 

Pole OneToOneField reprezentuje relację jeden do jednego między dwoma modelami. W tej relacji jedna instancja modelu może być powiązana tylko z jedną instancją innego modelu. Na przykład, kraj może mieć tylko jedną stolicę, a stolica może należeć tylko do jednego kraju. Aby utworzyć relację OneToOneField, definiujesz pole OneToOneField w jednym z modeli.

 

OneToOneField

 

Pole OneToOneField reprezentuje relację jeden do jednego między dwoma modelami. W tej relacji jedna instancja modelu może być powiązana tylko z jedną instancją innego modelu. Na przykład, kraj może mieć tylko jedną stolicę, a stolica może należeć tylko do jednego kraju. Aby utworzyć relację OneToOneField, definiujesz pole OneToOneField w jednym z modeli.

 

ManyToManyField

 

Pole ManyToManyField reprezentuje relację wiele do wielu między dwoma modelami. W tej relacji jedna instancja modelu może być powiązana z wieloma instancjami innego modelu, i na odwrót. Na przykład, studenci i kursy mogą mieć relację wiele do wielu, gdzie student może zapisać się na wiele kursów, a kurs może mieć wielu studentów. Aby utworzyć relację ManyToManyField, definiujesz pole ManyToManyField w jednym z modeli.

 

W kolejnej sekcji skonfigurujemy przykład z użyciem krajów, stolic i miast, aby pokazać, jak implementować te relacje w Django.

 

 

Przykład relacji między modelami: Kraje, Stolice i Miasta

 

Aby zademonstrować użycie ForeignKey, OneToOneField i ManyToManyField w Django, stworzymy prostą aplikację zarządzającą krajami, stolicami i miastami. Relacje między tymi modelami są następujące:

 

1. Kraj może mieć wiele miast (one-to-many)

 

2. Kraj ma jedną stolicę (one-to-one)

 

3. Miasto może mieć wiele atrakcji turystycznych, a atrakcja turystyczna może być odwiedzana przez turystów z wielu miast (many-to-many)

 

W tym przykładzie użyjemy modelu Country do reprezentowania krajów, modelu Capital do reprezentowania stolic i modelu City do reprezentowania innych miast. Stworzymy również model TouristAttraction do reprezentowania atrakcji turystycznych i ich relacji z miastami.

 

W kolejnych sekcjach przejdziemy przez proces implementacji tych modeli w Django i pokażemy, jak korzystać z ORM Django do interakcji z nimi.

 

 

Implementacja modeli w Django

 

Aby zacząć, musimy zdefiniować nasze modele w Django. Modele w Django to specjalne klasy Pythona, które reprezentują tabele w bazie danych. Atrybuty tych klas odpowiadają kolumnom w tabelach.

 

Tworzenie modelu Country

 

Zacznijmy od utworzenia modelu Country. Każdy kraj będzie miał nazwę, która jest unikalna.

 

from django.db import models

class Country(models.Model):
    name = models.CharField(max_length=100, unique=True)

    def __str__(self):
        return self.name

 

 

Tworzenie modelu Capital

 

Następnie utworzymy model Capital. Każda stolica będzie miała nazwę i będzie powiązana z jednym krajem przez relację OneToOneField.

 

class Capital(models.Model):
    name = models.CharField(max_length=100, unique=True)
    country = models.OneToOneField(Country, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

 

 

Tworzenie modelu City

 

Następnie utworzymy model City. Każde miasto będzie miało nazwę i będzie powiązane z jednym krajem przez relację ForeignKey.

 

class City(models.Model):
    name = models.CharField(max_length=100)
    country = models.ForeignKey(Country, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

 

 

Tworzenie modelu TouristAttraction

 

Na koniec utworzymy model TouristAttraction. Każda atrakcja turystyczna będzie miała nazwę i będzie powiązana z wieloma miastami przez relację ManyToManyField.

 

class TouristAttraction(models.Model):
    name = models.CharField(max_length=100)
    cities = models.ManyToManyField(City)

    def __str__(self):
        return self.name

 

 

Teraz, gdy nasze modele są gotowe, możemy użyć ORM Django do tworzenia, odpytywania, aktualizowania i usuwania powiązanych danych.

 

 

Korzystanie z ORM Django do interakcji z modelami

 

ORM Django pozwala na interakcję z modelami w sposób Pythonowy, bez pisania skomplikowanych zapytań SQL. W tej sekcji pokażemy, jak tworzyć instancje naszych modeli, odpytywać powiązane dane, aktualizować powiązane dane i usuwać powiązane dane.

 

Zanim zaczniemy, wejdźmy do powłoki Django, aby wykonać kod interaktywnie. Aby to zrobić, uruchom następujące polecenie w terminalu:

 

python manage.py shell

 

 

Po wejściu do powłoki Django możesz zaimportować swoje modele i zacząć z nimi pracować.

 

 

Tworzenie Modeli

 

Aby tworzyć instancje naszych modeli, możemy skorzystać z metody create dostarczanej przez menedżer modelu. Na przykład możemy stworzyć kraj, stolicę i miasto w ten sposób:

 

from myapp.models import Country, Capital, City

country = Country.objects.create(name="Exampleland")

capital = Capital.objects.create(name="Example City", country=country)
city = City.objects.create(name="Another City", country=country)

 

 

Tworzenie Queryset

 

Możemy korzystać z ORM Django do odpytywania powiązanych danych. Na przykład możemy uzyskać wszystkie miasta powiązane z krajem w ten sposób:

 

cities = City.objects.filter(country=country)

 

 

Możemy aktualizować powiązane dane, aktualizując pola powiązanych instancji i wywołując na nich metodę save. Na przykład możemy zaktualizować nazwę miasta w ten sposób:

 

capital = Capital.objects.get(country=country)

 

 

Aktualizacja powiązanych danych

 

We can update related data by updating the fields of the related instances and calling the save method on them. For example, we can update the name of a city like this:

 

country_1 = country.objects.get(capital=Berlin)

country_1.name = "New Name"
country_1.save()

 

 

Usuwanie powiązanych danych

 

Możemy usuwać powiązane dane, wywołując na powiązanych instancjach metodę delete. Na przykład możemy usunąć miasto w ten sposób:

 

country1.delete()

 

 

Zauważ, że metoda delete usunie również wszelkie powiązane instancje z relacją ForeignKey lub OneToOneField, które mają ustawione on_delete=models.CASCADE.

 

W następnej sekcji pokażemy, jak wyświetlać powiązane dane w szablonach Django przy użyciu frameworka CSS Bootstrap.

 

 

Wyświetlanie powiązanych danych w szablonach

 

Teraz, gdy mamy nasze modele i dane ustawione, wyświetlmy powiązane dane w szablonach Django. W tej sekcji pokażemy, jak tworzyć szablony do wyświetlania danych o kraju, stolicy i miastach, a także jak korzystać z frameworka CSS Bootstrap do stylizacji.

 

Korzystanie z Bootstrap do stylizacji

 

Aby użyć Bootstrap w naszych szablonach, najpierw musimy dołączyć pliki CSS i JavaScript Bootstrap do szablonu base.html. Możesz pobrać pliki i dołączyć je lokalnie lub skorzystać z CDN. Dla uproszczenia skorzystamy z opcji CDN. Dodaj następujące linie do sekcji head i body pliku base.html:

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Country, Capital, and City Data</title>
    <!-- Add Bootstrap CSS -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    {% block content %}{% endblock %}
    <!-- Add Bootstrap JS and jQuery -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

 

 

Tworzenie szablonów do wyświetlania danych

 

Teraz, gdy mamy ustawiony framework Bootstrap, stwórzmy szablony do wyświetlania naszych danych. Stworzymy szablon do wyświetlania listy krajów i ich stolic, a także inny szablon do wyświetlania miast i atrakcji turystycznych dla konkretnego kraju.

 

Stwórz szablon o nazwie country_list.html i dodaj do niego następujący kod:

 

{% extends "base.html" %}

{% block content %}
    <h1>Countries and Capitals</h1>
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Country</th>
                <th>Capital</th>
            </tr>
        </thead>
        <tbody>
            {% for country in countries %}
                <tr>
                    <td>{{ country.name }}</td>
                    <td>{{ country.capital.name }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

 

Stwórz szablon o nazwie country_detail.html i dodaj do niego następujący kod:

{% extends "base.html" %}

{% block content %}
    <h1>{{ country.name }}</h1>
    <h2>Cities</h2>
    <ul>
        {% for city in country.city_set.all %}
            <li>{{ city.name }}</li>
        {% endfor %}
    </ul>
{% endblock %}

 

 

W swoich views możesz teraz renderować te szablony i przekazywać do nich potrzebne dane. Na przykład możesz stworzyć widok do wyświetlania listy krajów i ich stolic tak jak to:

 

from django.shortcuts import render
from .models import Country

def country_list(request):
    countries = Country.objects.all()
    return render(request, 'country_list.html', {'countries': countries})

 

 

A możesz stworzyć widok do wyświetlania szczegółów konkretnego kraju tak jak to:

 

from django.shortcuts import render, get_object_or_404
from .models import Country

def country_detail(request, country_id):
    country = get_object_or_404(Country, pk=country_id)
    return render(request, 'country_detail.html', {'country': country})

 

 

Aby wyświetlić atrakcje turystyczne dla każdego miasta, zmodyfikuj szablon country_detail.html w następujący sposób:

 

{% extends "base.html" %}

{% block content %}
    <h1>{{ country.name }}</h1>
    <h2>Cities</h2>
    <ul>
        {% for city in country.city_set.all %}
            <li>
                {{ city.name }}
                <ul>
                    <strong>Tourist Attractions:</strong>
                    {% for attraction in city.touristattraction_set.all %}
                        <li>{{ attraction.name }}</li>
                    {% endfor %}
                </ul>
            </li>
        {% endfor %}
    </ul>
{% endblock %}

 

 

Teraz masz szablony do wyświetlania listy krajów ze swoimi stolicami, a także szczegółowy widok konkretnego kraju z jego miastami i atrakcjami turystycznymi. Szablony korzystają z frameworka CSS Bootstrap do stylizacji.

 

 

Podsumowanie

 

W tym wpisie omówiliśmy, jak pracować z danymi relacyjnymi w Django, omawiając relacje ForeignKey, OneToOneField i ManyToManyField. Ustawiliśmy również przykład z krajami, stolicami i miastami, aby pokazać, jak implementować te relacje w modelach Django.

 

Następnie użyliśmy ORM Django do tworzenia, zapytań, aktualizacji i usuwania powiązanych danych. Dodatkowo pokazaliśmy, jak wyświetlać te powiązane dane w szablonach Django, używając do stylizacji frameworka CSS Bootstrap.

 

Rozumiejąc i wykorzystując potężne funkcje Django do pracy z danymi relacyjnymi, możesz tworzyć bardziej złożone i efektywne aplikacje internetowe. Kontynuując budowę swoich projektów Django, pamiętaj, aby wykorzystać potężne narzędzia i techniki wbudowane omówione w tym poście do skutecznego zarządzania relacjami między twoimi modelami.

 

Dyskusja

Twój komentarz

Tagi