در جنگو، مدیریتکننده مدل (Model Manager) ابزاری است که به شما امکان میدهد عملیاتهای پیچیدهتری را روی کوئریهای پایگاه داده انجام دهید و عملکرد برنامه خود را بهینهسازی کنید. مدیران مدل برای ایجاد متدهایی استفاده میشوند که به طور پیشفرض کوئریهایی را که معمولاً برای یک مدل انجام میدهید، سازماندهی و بهینهسازی کنند.
۱. مدیریتکنندههای مدل پیشفرض جنگو
هر مدل در جنگو به طور پیشفرض یک مدیر مدل (objects) دارد که به شما اجازه میدهد عملیاتهای معمولی مانند بازیابی دادهها را انجام دهید. به عنوان مثال:
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()
# استفاده از مدیر پیشفرض برای دریافت تمام کتابها
books = Book.objects.all()
۲. ایجاد یک مدل Manager سفارشی
اگر بخواهید روشهای خاصی برای انجام کوئریها ایجاد کنید، میتوانید یک مدیر مدل سفارشی بسازید. برای این کار باید یک کلاس جدید بسازید که از models.Manager ارثبری کند و متدهای مورد نظر خود را به آن اضافه کنید.
مثال: در این مثال، مدیر مدل سفارشی را برای فیلتر کردن کتابها بر اساس تاریخ انتشار میسازیم.
def published_recently(self):
return self.filter(published_date__gte="2024-01-01")
def books_by_author(self, author_name):
return self.filter(author=author_name)
۳. استفاده از متدهای Model Manager برای بهینهسازی کوئریها
مدیر مدلها نه تنها برای فیلتر کردن دادهها استفاده میشود، بلکه میتواند به بهینهسازی کوئریها نیز کمک کند. در اینجا چند روش برای بهینهسازی کوئریها با استفاده از مدیران مدل آورده شده است:
الف. استفاده از select_related و prefetch_related
اگر مدل شما ارتباطات خارجی داشته باشد (مثل ارتباطات ForeignKey یا ManyToMany)، استفاده از select_related و prefetch_related میتواند تعداد کوئریها را کاهش دهد و عملکرد را بهبود بخشد.
- select_related برای ارتباطات یک به یک (One-to-One) و یک به چند (One-to-Many) استفاده میشود. این متد کوئریها را بهینهسازی میکند و تمام دادههای مرتبط را در یک کوئری بارگذاری میکند.
مثال:
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
class Author(models.Model):
name = models.CharField(max_length=100)
# استفاده از select_related برای بارگذاری همزمان کتابها و نویسندگان
books = Book.objects.select_related('author').all()
- prefetch_related برای ارتباطات چند به چند (Many-to-Many) و ارتباطات معکوس استفاده میشود. این متد به طور جداگانه کوئریهای جداگانه برای دادههای مرتبط ایجاد میکند و پس از آن آنها را ترکیب میکند.
مثال:
name = models.CharField(max_length=100)
class Course(models.Model):
title = models.CharField(max_length=100)
students = models.ManyToManyField(Student)
# استفاده از prefetch_related برای بارگذاری همزمان دانشآموزان در هر دوره
courses = Course.objects.prefetch_related('students').all()
ب. استفاده از annotate و aggregate
اگر نیاز به انجام عملیات روی دادهها مانند جمع، میانگین یا تعداد دارید، میتوانید از annotate و aggregate استفاده کنید تا این محاسبات در سطح پایگاه داده انجام شود و نیاز به پردازش اضافی در پایتون نباشد.
- annotate: برای افزودن محاسبات به هر رکورد در کوئری استفاده میشود.
مثال:
# تعداد کتابهایی که هر نویسنده نوشته است
authors = Author.objects.annotate(num_books=Count('book'))
- aggregate: برای انجام محاسبات روی تمام رکوردهای مدل استفاده میشود.
مثال:
# میانگین تعداد صفحات کتابها
average_pages = Book.objects.aggregate(Avg('pages'))
۴. مدیریت کوئریها با متدهای Model Manager
استفاده از متدهای Model Manager به شما این امکان را میدهد که کوئریهای پیچیده را به صورت تجرید شده و با استفاده از متدهای خوانا و منطقی اجرا کنید. به این ترتیب، شما میتوانید برنامهتان را تمیزتر و مقیاسپذیرتر نگه دارید.
نتیجهگیری
مدیر مدلها در جنگو ابزار قدرتمندی برای بهینهسازی کوئریها و انجام عملیاتهای پیچیده است. با استفاده از مدیران مدل سفارشی، شما میتوانید متدهای خاصی را برای انجام کوئریهای پیچیده، بهینهسازی عملکرد با استفاده از select_related و prefetch_related، و انجام عملیاتهای محاسباتی با annotate و aggregate اضافه کنید. این امر به شما کمک میکند تا عملکرد پایگاه داده خود را بهبود بخشید و کدهای پیچیده را سادهتر کنید.
