ویرگول
ورودثبت نام
رضا رضایی
رضا رضاییبرنامه نویس پایتون و توسعه دهنده نرم افزارهای سمت سرور با تخصص در فریمورک جنگو
رضا رضایی
رضا رضایی
خواندن ۵ دقیقه·۵ ساعت پیش

فصل اول - اپیزود ۷ - ترجمه کتاب Django 5 By Example

ترجمه کتاب Django 5 By Example from Anotino Melé - پیاده سازی مرتب‌سازی پیشفرض، اندیس پایگاه داده و فعال سازی اپلیکیشن
ترجمه کتاب Django 5 By Example from Anotino Melé - پیاده سازی مرتب‌سازی پیشفرض، اندیس پایگاه داده و فعال سازی اپلیکیشن

تعیین ترتیب پیش‌فرض برای مرتب‌سازی

پست‌های وبلاگ معمولاً به ترتیب زمانی معکوس (از جدید به قدیم) نمایش داده می‌شوند، به طوری که جدیدترین پست‌ها ابتدا مشاهده شوند. ما برای مدل خود، یک ترتیب پیش‌فرض (Default Ordering) تعریف خواهیم کرد. این ترتیب هنگام بازیابی (Retrieving) اشیاء از پایگاه داده اعمال می‌شود، مگر اینکه در کوئری (Query) خاصی، ترتیب متفاوتی تعیین شده باشد.

فایل models.py در اپلیکیشن blogرا مطابق قطعه کد زیر ویرایش کنید:

from django.db import models from django.utils import timezone class Post(models.Model): title = models.CharField(max_length=250) slug = models.SlugField(max_length=250) body = models.TextField() publish = models.DateTimeField(default=timezone.now) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) class Meta: ordering = ['-publish'] def __str__(self): return self.title

ما یک کلاس Meta در داخل مدل اضافه کرده‌ایم. این کلاس، متاداده‌ها (Metadata) مربوط به مدل را تعریف می‌کند. ما از ویژگی (Attribute) ordering استفاده می‌کنیم تا به جنگو بگوییم که نتایج را بر اساس فیلد publish مرتب کند. این ترتیب مرتب‌سازی، به‌صورت پیش‌فرض برای کوئری‌های دیتابیس اعمال خواهد شد، مگر اینکه ترتیب خاص دیگری در خودِ کوئری تعیین شده باشد. ما با استفاده از یک خط تیره (-) قبل از نام فیلد (-publish)، ترتیب نزولی (Descending) را مشخص می‌کنیم. در نتیجه، پست‌ها به‌صورت پیش‌فرض با ترتیب زمانی معکوس (از جدید به قدیم) بازگردانده خواهند شد.


افزودن ایندکس (Index) به پایگاه داده

بیایید یک ایندکس پایگاه داده برای فیلد publish تعریف کنیم. این کار باعث بهبود عملکرد (Performance) در هنگام فیلتر کردن کوئری‌ها یا مرتب‌سازی نتایج بر اساس این فیلد می‌شود. باتوجه به اینکه نتایج را به صورت پیشفرض بر اساس فیلد publish مرتب می‌کنیم درنتیجه کوئری‌های خیلی زیادی از این ایندکس استفاده میکنند و باعث افزایش سرعت کوئری می‌شود.

فایل models.py در اپلیکیشن blog را مطابق الگوی زیر ویرایش کنید:

from django.db import models from django.utils import timezone class Post(models.Model): title = models.CharField(max_length=250) slug = models.SlugField(max_length=250) body = models.TextField() publish = models.DateTimeField(default=timezone.now) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) class Meta: ordering = ['-publish'] indexes = [ models.Index(fields=['-publish']), ] def __str__(self): return self.title

ما گزینه indexes را به کلاس Meta مدل اضافه کرده‌ایم. این گزینه به شما اجازه می‌دهد ایندکس‌های پایگاه داده را برای مدل خود تعریف کنید؛ این ایندکس‌ها می‌توانند شامل یک یا چند فیلد، با ترتیب صعودی یا نزولی، و یا حتی عبارات عملکردی (Functional Expressions) و توابع دیتابیس باشند. ما یک ایندکس برای فیلد publish اضافه کردیم. با استفاده از یک خط تیره قبل از نام فیلد، ایندکس را مشخصاً با ترتیب نزولی(ِDecsending) تعریف کرده‌ایم. فرآیند ایجاد این ایندکس، در عملیات مهاجرت پایگاه داده (Database Migrations) که در مراحل بعد برای مدل‌های وبلاگ خود ایجاد می‌کنیم، گنجانده خواهد شد.

نکته مهم: قابلیت تعیین ترتیب (Ordering) در ایندکس، در MySQL پشتیبانی نمی‌شود. اگر از MySQL به عنوان پایگاه داده استفاده می‌کنید، یک ایندکس نزولی در واقع به صورت یک ایندکس معمولی (صعودی) ساخته خواهد شد.


فعال‌سازی اپلیکیشن blog

اکنون وقت آن رسیده که اپلیکیشن خود را جهت فعال‌سازی در پروژه‌مان به سیستم جنگو معرفی شود.
این کار باعث می‌شود جنگو پیگیر تغییرات اپلیکیشن باشد و همچنین بتواند جداول پایگاه داده را بر اساس مدل‌ها بسازد.

برای این کار باید فایل settings.py را ویرایش کنید و آیتم "blog.apps.BlogConfig" را به لیستی تحت عنوان INSTALLED_APPS اضافه کنید: مانند نمونه کد زیر:

INSTALLED_APPS in settings.py
INSTALLED_APPS in settings.py

کلاس BlogConfig تنظیمات مربوط به این اپلیکیشن را مشخص می‌کند. با این کار جنگو متوجه می‌شود که این اپلیکیشن در این پروژه فعال شده است و از این پس می‌تواند مدل‌های آن را بارگزاری کند.


اضافه کردن یک فیلد وضعیت انتشار

یکی از قابلیت‌های رایج در وبلاگ‌ها این است که نوشته‌ها تا زمانی که آماده انتشار شوند، به صورت پیش‌نویس (Draft) ذخیره شوند. ما یک فیلد status به مدل خود اضافه می‌کنیم که به ما اجازه می‌دهد وضعیت پست‌های وبلاگ را مدیریت کنیم. برای پست‌ها از دو وضعیت Draft و Published استفاده خواهیم کرد.

فایل models.py در اپلیکیشن blog را ویرایش کنید تا به شکل زیر درآید:

status field in Post model
status field in Post model

ما کلاس شمارشی (Enumeration) به نام Status را با ارث‌بری از models.TextChoices تعریف کرده‌ایم. گزینه‌های موجود برای وضعیت پست عبارت‌اند از:

  • DRAFT

  • PUBLISHED

مقادیر آن‌ها به ترتیب:

  • DF

  • PB

و نام‌های نمایشی آن‌ها به ترتیب:

  • Draft

  • Published

جنگو نوع‌هایی از enumeration ارائه می‌دهد که می‌توانید از آن‌ها ارث‌بری کنید تا گزینه‌ها (choices) را به شکل ساده‌تری تعریف کنید. این نوع‌ها بر پایه شیء enum در کتابخانه استاندارد پایتون ساخته شده‌اند.

برای مطالعه بیشتر درباره enum می‌توانید به این لینک مراجعه کنید:

https://docs.python.org/3/library/enum.html

نوع‌های enumeration در جنگو چند تغییر نسبت به enum استاندارد دارند. درباره این تفاوت‌ها می‌توانید در مستندات جنگو مطالعه کنید:

https://docs.djangoproject.com/en/5.0/ref/models/fields/#enumeration-types

ما می‌توانیم از ویژگی‌های زیر استفاده کنیم:

  • Post.Status.choices

    برای دریافت همه گزینه‌های قابل انتخاب

  • Post.Status.names

    برای دریافت نام گزینه‌ها

  • Post.Status.labels

    برای دریافت نام‌های نمایشی

  • Post.Status.values

    برای دریافت مقادیر واقعی گزینه‌ها

اکنون ما یک فیلد جدید به نام status به مدل اضافه کرده‌ایم که از نوع CharField است. این فیلد شامل پارامتر choices است که مقدار آن را به گزینه‌های تعریف‌شده در Status محدود می‌کند.

همچنین با استفاده از پارامتر default یک مقدار پیش‌فرض برای این فیلد تعیین کرده‌ایم. در اینجا مقدار پیش‌فرض DRAFT در نظر گرفته شده است.

یک روش خوب در طراحی مدل‌ها این است که choices را داخل همان کلاس مدل تعریف کنید و از enumeration types استفاده کنید. این کار باعث می‌شود بتوانید در هر جای کد به راحتی به label، value یا name گزینه‌ها دسترسی داشته باشید.

برای مثال می‌توانید مدل Post را import کنید و در هر جای کد از مقدار زیر به عنوان مرجع وضعیت پیش‌نویس استفاده کنید:

Post.Status.DRAFT

بیایید ببینیم چگونه می‌توان با status choices کار کرد.

دستور زیر را در ترمینال اجرا کنید تا Python shell باز شود:

python manage.py shell

سپس خطوط زیر را وارد کنید:

>>> from blog.models import Post >>> Post.Status.choices

در این حالت، گزینه‌های enum به صورت جفت‌های مقدار و نام نمایشی (value-label pairs) نمایش داده می‌شوند، مانند:

[('DF', 'Draft'), ('PB', 'Published')]

خط زیر را وارد کنید:

Post.Status.labels

در این صورت، نام‌های خوانا برای انسان (human-readable names) از اعضای enum را دریافت می‌کنید:

['Draft', 'Published']

خط زیر را وارد کنید:

Post.Status.values

در این حالت، مقادیر واقعی اعضای enum را دریافت خواهید کرد. این‌ها همان مقادیری هستند که در پایگاه داده برای فیلد status ذخیره می‌شوند:

['DF', 'PB']

خط زیر را وارد کنید:

Post.Status.names

در نتیجه، نام گزینه‌ها (names) را دریافت می‌کنید:

['DRAFT', 'PUBLISHED']

همچنین می‌توانید به یک عضو خاص از enumeration به این شکل دسترسی داشته باشید:

pythonPost.Status.PUBLISHED

و می‌توانید به ویژگی‌های آن نیز دسترسی پیدا کنید:

  • Post.Status.PUBLISHED.name

  • Post.Status.PUBLISHED.value

این ویژگی‌ها به ترتیب نام عضو enum و مقدار واقعی آن را برمی‌گردانند.


پست قبلی: (فصل اول - اپیزود ۶ - ترجمه کتاب Django 5 By Example)

پست بعدی: (فصل اول - اپیزود 8 - رابطه یک به چند کاربر نویسنده به پست‌ها و مایگرشن به دیتابیس)

کم کم داره جذاب میشه کتاب و پیشنهاد میکنم شمایی که تا اینجا همراه با من بودید، ادامه کتاب رو از دست ندید👍😉

ترجمه کتاب
۱
۰
رضا رضایی
رضا رضایی
برنامه نویس پایتون و توسعه دهنده نرم افزارهای سمت سرور با تخصص در فریمورک جنگو
شاید از این پست‌ها خوشتان بیاید