سروش ذاکر شبیری
سروش ذاکر شبیری
خواندن ۳ دقیقه·۴ سال پیش

میکرونکات جنگو - بخش دوم (models.py)

Django Models Micro Tips By Soroush Zaker Shobeiri
Django Models Micro Tips By Soroush Zaker Shobeiri

در ادامه بخش اول میکرونکات جنگو در این مطلب نکات مهمی که درباره فایل models داریم رو بیان میکنم و امیدوارم براتون مفید باشه.

models.py:

  • یکی از best practice ها در طراحی modelهامون اینه که برای هر کلاس متد get_absolute_url رو تعریف کنیم. برای مثال:
def get_absolute_url(self): return reverse('post-detail', args=[str(self.id)])

اگر این متد رو داخل مدل ها پیاده سازی کرده باشیم، در صورتی که از Template استفاده میکنیم میتونیم به جای

{% 'post_detail' post.pk %}

از

{% post.get_absolute_url %}

استفاده کنیم.

  • براساس پیشنهاد داکیومنت خود جنگو اگر فکر می کنید که در آینده نیاز دارید تا فیلد های بیشتری به مدل یوزر خود جنگو اضافه کنید بهتره این کار رو در ابتدای پروژه انجام بدید، به بیان دیگه بهتره همیشه اول پروژه ها یه custom user model برای خودمون بسازیم.
  • برای اضافه کردن custom user model بهتره که از کلاس AbstractUser به جای AbstractBaseUser استفاده کنیم.
  • تفاوت null=True و blank=True در مدل ها چیه؟
برای جواب دادن به این سوال پیشنهاد میکنم این پست استک اورفلو رو بخونید.

به طور خلاصه null=True مربوط به نگهداری مقادیر در دیتابیس هست که ما اجازه میدیم تا مقادیر null در دیتابیس ذخیره بشن. اما blank=True مربوط به مرحله validation فیلدها است که مشخص میکنه آیا این فیلد required هست یا خیر.

استفاده همزمان null=True و ‌blank=True خیلی اتفاق می افته و دلیلش هم اینه که وقتی ما یک فیلد رو غیر الزامی تعیین میکنیم (blank=True) در نتیجه این اجازه رو هم باید به دیتابیس بدیم تا مقادیر null رو ذخیره کنه. تنها استثنا این موضوع در مورد CharField و TextField هست که در صورتی که خالی باشند به صورت یک string خالی یا ' ' داخل دیتابیس ذخیر میشن.

  • یکی دیگه از best practice ها اینه که تا حد امکان تغییرات هر model رو داخل migration همون model یا app انجام بدیم نه اینکه یهو با یه migration همه model هایی که نیاز داریم رو ایجاد کنیم.
  • مثلا ما یک مدل پست داریم و هر پست می تونه چندین کامنت داشته باشه در این صورت حتما داخل مدل کامنت یک Foreign Key داریم به مدل پست حالا اگر بخوایم کامنت های یک پست رو از طریق یک کوئری دریافت کنیم چیکار باید کنیم؟

راه حلی که اینجا جنگو به ما میده قابلیت اییه که بهش میگیم foo_set در اینجا foo معادل با مدل پست های ما است یعنی مثلا post_set که از این طریق داخل کوئری هامون میتونیم به FKها دسترسی داشته باشیم.

روش دیگه تعریف کردن related_name عه مثلا:

class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')

بهتره related_name اسم جمع اون مدل ایی باشه که FK درونش قرار داره.

  • تفاوت id و pk:

خیلی از جاها ما این دوتا رو به جای هم استفاده می کنیم چون به صورت پیش فرض جنگو موقع ایجاد جدول های دیتابیس یک فیلد id ایجاد می کنه و اون رو به عنوان pk یا همون primary key در نظر میگیره.

اما ما این قابلیت رو داریم که فیلد دیگه ایی رو (بغیر از id) بعنوان pk در نظر بگیریم. در نتیجه استفاده از pk به جای id روش safe تری محسوب میشه و تشخیص اینکه کدوم فیلد بعنوان pk در نظر گرفته شده بعهده خود جنگوست.

  • بهتره وقتی که میخوایم داخل یک model به User model رفرنس ایجاد کنیم ( یعنی همون FK مثلا یک مدل پست داریم و هر پست یک نویسنده داره.) به جای نوشتن اسم مدل یوزر در قسمت FK از متد get_user_model استفاده کنیم.
author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name='posts')


من سروش ذاکر شبیری هستم و ممنونم که این مطلب رو مطالعه کردید. در صورتی که سوال یا پیشنهادی داشتید خوشحال میشم که اون رو از طریق راه های زیر با من در میون بزارید. :)
اگر این مطلب رو دوست داشتید می تونید بخش اول رو در این لینک بخونید.


پایتونبرنامه نویسیpythondjango
یه برنامه نویس که دوست داره همیشه مطالب جدیدی رو یادبگیره و اونهارو با دیگران به اشتراک بزاره.
شاید از این پست‌ها خوشتان بیاید