~2 دقیقه مطالعه • بروزرسانی ۱۹ اسفند ۱۴۰۴
۱. تعریف رابطهٔ چندبهچند
برای تعریف رابطهٔ many-to-many از ManyToManyField استفاده میکنیم.
در مثال زیر، یک Article میتواند در چند Publication منتشر شود و هر Publication نیز چند Article دارد.
class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
۲. ایجاد دادهها
ایجاد Publication:
p1 = Publication(title="The Python Journal"); p1.save()
p2 = Publication(title="Science News"); p2.save()
p3 = Publication(title="Science Weekly"); p3.save()
ایجاد Article:
a1 = Article(headline="Django lets you build web apps easily")
تا زمانی که Article ذخیره نشده باشد، نمیتوان رابطهٔ M2M را تنظیم کرد:
a1.publications.add(p1) # خطا
پس ابتدا ذخیره میکنیم:
a1.save()
a1.publications.add(p1)
۳. افزودن چند رابطه
a2 = Article(headline="NASA uses Python"); a2.save()
a2.publications.add(p1, p2)
a2.publications.add(p3)
افزودن تکراری مشکلی ندارد:
a2.publications.add(p3) # تکراری → نادیده گرفته میشود
افزودن نوع اشتباه خطا میدهد:
a2.publications.add(a1) # TypeError
۴. ایجاد و افزودن در یک مرحله
new_pub = a2.publications.create(title="Highlights for Children")
۵. دسترسی به رابطهها
از سمت Article:
a1.publications.all()
a2.publications.all()
از سمت Publication (سمت معکوس):
p1.article_set.all()
p2.article_set.all()
۶. کوئریزدن روی رابطهٔ M2M
جستجو با id یا pk:
Article.objects.filter(publications__id=1)
Article.objects.filter(publications=p1)
فیلتر روی فیلدهای Publication:
Article.objects.filter(publications__title__startswith="Science")
برای جلوگیری از تکرار:
Article.objects.filter(publications__title__startswith="Science").distinct()
جستجو با لیست:
Article.objects.filter(publications__in=[p1, p2]).distinct()
۷. کوئری از سمت معکوس (Publication → Article)
Publication.objects.filter(article__headline__startswith="NASA")
Publication.objects.filter(article__in=[a1, a2]).distinct()
۸. حذف از رابطه
حذف از سمت Article:
a4.publications.remove(p2)
حذف از سمت Publication:
p2.article_set.remove(a5)
۹. set و clear
تنظیم مجموعهٔ رابطه:
a4.publications.set([p3])
پاککردن همهٔ رابطهها:
a4.publications.clear()
p2.article_set.clear()
۱۰. رفتار هنگام حذف آبجکتها
حذف Publication:
p1.delete()
a1.publications.all() # خالی
حذف Article:
a2.delete()
p2.article_set.all() # خالی
۱۱. Bulk delete و رفتار رابطهها
حذف گروهی Publication:
Publication.objects.filter(title__startswith="Science").delete()
a2.publications.all() # فقط موارد باقیمانده
حذف گروهی Article:
q = Article.objects.filter(headline__startswith="Django")
q.delete()
q.all() # خالی
جمعبندی
رابطهٔ ManyToMany در Django یکی از قدرتمندترین ابزارهای ORM است.
با استفاده از متدهای add، remove، set، clear و create میتوان رابطهها را بهصورت کامل مدیریت کرد.
همچنین Django امکان کوئریزدن از هر دو سمت رابطه را فراهم میکند و رفتار رابطهها هنگام حذف آبجکتها کاملاً قابل پیشبینی است.
نوشته و پژوهش شده توسط دکتر شاهین صیامی