Sobes.tech
Middle

Ինչպես իրականացնել շատ-մի հարաբերություն Django-ում?

sobes.tech AI

Պատասխան AI-ից

Դժգույն Django-ում "շատ-շատ" հարաբերությունը (many-to-many) իրականացնում է ManyToManyField դաշտի միջոցով: Այս դաշտը կապում է երկու մոդելներ՝ ստեղծելով միջնորդական աղյուսակ տվյալների բազայում, որը պահպանում է կապերը:

Նկատենք, որ ունենք Author և Book մոդելներ: Մի գրք կարող է գրել մի քանի հեղինակ, և մի հեղինակ կարող է գրել մի քանի գրքեր:

# models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author) # ManyToManyField դաշտ

    def __str__(self):
        return self.title

Երբ ավելացնում ենք ManyToManyField Book մոդելին, Django ինքնաբերաբար ստեղծում է միջնորդական աղյուսակ՝ սովորաբար անվանմամբ appname_book_authors, որը կապում է Book և Author մոդելները: Այս աղյուսակը կունենա արտաքին բանալիներ՝ book_id և author_id:

Կարող եք աշխատել այս հարաբերության հետ հետևյալ սինտաքսիսով:

Հեղինակների ավելացում գրքի համար:

# Օրինակ օգտագործում
from myapp.models import Author, Book

author1 = Author.objects.create(name="Լև Տոլստոյ")
author2 = Author.objects.create(name="Ֆյոդոր Դոստոևսկի")

book = Book.objects.create(title="Երկիր և խաղաղություն")
book.authors.add(author1)
book.authors.add(author2) # Հեղինակների ավելացում գրքի համար

Բոլոր գրքերը հեղինակի համար:

author = Author.objects.get(name="Լև Տոլստոյ")
books_by_tolstoy = author.book_set.all() # Հետադարձ հարաբերություն

# Հետադարձ հարաբերությունը հասանելի է ըստ նախնական կարգավորման՝ "_set"
# Հետադարձ հարաբերության անունը կարելի է փոխել `related_name`-ով

Բոլոր հեղինակները գրքի համար:

book = Book.objects.get(title="Երկիր և խաղաղություն")
authors_of_book = book.authors.all() # Հասանելիություն կապակցված հեղինակներին

Հեղինակների հեռացում գրքից:

book = Book.objects.get(title="Երկիր և խաղաղություն")
author1 = Author.objects.get(name="Լև Տոլստոյ")
book.authors.remove(author1) # Հեղինակին հեռացում գրքից

Բոլոր հեղինակների մաքառում գրքից:

book = Book.objects.get(title="Երկիր և խաղաղություն")
book.authors.clear() # Բոլոր հեղինակների հեռացում

Միաժամանակ մի քանի հեղինակների ավելացում:

book = Book.objects.get(title="Երկիր և խաղաղություն")
author3 = Author.objects.create(name="Միխայիլ Բուլգակով")
author4 = Author.objects.create(name="Անտոն Չեխով")
book.authors.add(author3, author4) # Միաժամանակ մի քանի հեղինակների ավելացում

Լրացուցիչ հնարավորություններ:

  • through: Կարող եք սահմանել սեփական միջնորդական մոդելը՝ օգտագործելով through պարամետրը, եթե անհրաժեշտ է ավելացնել լրացուցիչ դաշտեր կապի մեջ (օրինակ՝ հեղինակին գրքում ավելացման ամսաթիվը):

    class Membership(models.Model):
        book = models.ForeignKey(Book, on_delete=models.CASCADE)
        author = models.ForeignKey(Author, on_delete=models.CASCADE)
        date_added = models.DateField()
    
    class Book(models.Model):
        title = models.CharField(max_length=200)
        authors = models.ManyToManyField(Author, through='Membership')
    
        def __str__(self):
            return self.title
    
  • related_name: Արժեք է փոխելու անունը, որը օգտագործվում է հետադարձ հարաբերության համար:

    class Author(models.Model):
        name = models.CharField(max_length=100)
        books = models.ManyToManyField('Book', related_name='published_by') # Հետադարձ հարաբերության անունը փոխվել է
    
        def __str__(self):
            return self.name
    
    # Այժմ գրքի համար կարելի է ստանալ հեղինակները՝
    # author = Author.objects.get(name="Լև Տոլստոյ")
    # books_by_author = author.books.all()
    # Իսկ գրքի հեղինակները՝
    # book = Book.objects.get(title="Երկիր և խաղաղություն")
    # authors_of_book = book.published_by.all()
    

Այսպիսով, ManyToManyField-ը հեշտացնում է "շատ-շատ" հարաբերությունների կառավարումը Django-ում՝ ավտոմատ կերպով ստեղծելով և կառավարելով համապատասխան միջնորդական աղյուսակը։