آموزش جنگو (Basic) : جلسه بیست | متد های مدل ها

در این جلسه به بررسی نوشتن متد های مدل (تابع های درون یک مدل) خواهیم پرداخت . با ما همراه باشید .آموزش جنگو : جلسه بیست | متد های مدل هامدل ها :متد های مدلشما میتوانید برای مدل خود متود هایی را تعریف کنید . متود ها توابعی هستند که کار آنها اعمال تغییراتی روی ردیف ها یا همان رکورد های دیتابیس است . هر رکورد میتواند تابع ما را بپذیرد و وابسته به آن کاری انجام بدهد.این متود ها کمک فراوانی به شما میکنند و باعث می شوند منطق مدل شما در خود مدل ذخیره شود . مثال زیر را نگاه کنید :from django.db import models class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() def baby_boomer_status(self): &quotReturns the person's baby-boomer status.&quot import datetime if self.birth_date < datetime.date(1945, 8, 1): return &quotPre-boomer&quot elif self.birth_date < datetime.date(1965, 1, 1): return &quotBaby boomer&quot else: return &quotPost-boomer&quot @property def full_name(self): &quotReturns the person's full name.&quot return '%s %s' %(self.first_name, self.last_name)نکته : اخرین متود در این مثال یک property می باشد .در آینده ما نگاهی به تمامی متود هایی که به صورت اتوماتیک برای هر کلاس وجود دارند ,خواهیم انداخت . ولی اکنون چندین متود پرکاربرد را بررسی میکنیم . این متود ها به صورت اتوماتیک برای هر کلاس تعریف میشوند و در صورت نیاز می توانید آنها را بازنویسی کنید تا رفتار آنها را تغییر دهید .متد ()___str___این متود که قبلا با آن اشنا شده اید ,نام یک شی (هر شی یک رکورد در دیتابیس نیز محسوب می شود) را به شما باز میگرداند . در حالت پیش فرض نام هر شی به صورت object (id) به صورتی که باز گردانده می شود که شما آن را در ادمین پنل ,هنگامی که می خواهید رکورد ها را ببینید ,در قسمت name مشاهده خواهید کرد .شما می توانید همچنین آن را بازنویسی کنید تا مقدار های جدیدی بجای مقدار قبلی به شما بازگرداند . به مثال زیر نگاه کنید . (در اینجا فیلد name را به عنوان نام هر شی باز گردانده ایم . اکنون در ادمین پنل بجای example object 1 به شما مقدار فیلد name هر رکورد نمایش داده می شود)from django.db import models class example(models.Model): name = models.CharField(max_lentgh=200) def__str__(): returnself.nameمتد ()get_absolute_urlاین متد به جنگو میگوید که چطور برای هر شی ساخته شده از آن کلاس , یک urlبسازد . جنگو از آن در ادمین پنل نیز استفاده می کند تا هر زمان که نیاز داشت , جزییات یک شی را در یک url که خود تولید کرده است ,نشان دهد . (منظور این است که شما از این متد برای هر شی استفاده میکنید تا کاربر را به صفحه ای حاوی اطلاعاتی خاص از آن شی هدایت کنید .)برای مثال در یک مدل مربوط به کالا ها باید آن را ایجاد کنید . و اگر app:detail آدرسی باشد که قرار است هر بار یک name را دریافت کند تا اطلاعات یک شی را نمایش دهد : (یعنی app/detail/<name>)from django.db import models From django.urls import reverse class example(models.Model): name = models.CharField(max_lentgh=200) def get_absolute_url(self): return reverse(‘app:detail’ , args=[self.name])حال با فراخوانی این متد برای هر شی میتوانید به مقدار urlساخته شده برای همان شی دسترسی پیدا کنید و آن را در فرانت اند در تگ <a> جایگذاری کنید . بعدا در مورد این مبحث بیشتر حرف خواهیم زد .مدل ها : بازنویسی متود های از پیش تعریف شده برای یک مدلمجموعه دیگری از متود ها برای یک کلاس وجود دارد که فرایند کپسوله سازی را انجام می دهند . مهمترین آنها متد های ()save() , delete هستند و شما گاهی نیاز دارید تا آنها را بازنویسی کنید . (متد ()save برای شما رکورد را در دیتابیس ذخیره میکند . گاهی نیاز دارید تا به طور دیگری رکورد شما ذخیره شود . در این حالت باید این متد را بازنویسی کنید و رفتار آن را تغییر دهید )شما مجاز هستید تا همه ی این متد ها را بازنویسی کنید و رفتار آنها را تغییر دهید .به مثال زیر نگاهی بیندازید . در مثال زیر دو تابع با نام do_something و do_something_else داریم که بر فرض وجود دارند و آنها را قرار است هر بار که متد ()save فراخوانی می شود ,آنها نیز فراخوانی شوند .from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def save(self, *args, **kwargs): do_something() super().save(*args, **kwargs) # این خط همیشه باید وجود داشته باشد do_something_else()همچنین می توانید در برخی از موارد از ذخیره شدن جلوگیری کنید . (در مثال زیر اگر self.name برابر با مقدار Yoko ono’s blog باشد , شی شما ذخیره نمی شود ولی در غیر این صورت مدل شما شی را ذخیره میکند .)from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def save(self, *args, **kwargs): if self.name == &quotYoko Ono's blog&quot: return # Yoko shall never have her own blog! else: super().save(*args, **kwargs) # Call the &quotreal&quot save() method.مهم است که به یاد داشته باشید که متد superclass را فراخوانی کنید . منظور این خط از کد :super().save(*args, **kwargs)است . این خط برای شما شی را ذخیره میکند و آن را درون دیتابیس سیو میکند . اگر آن را استفاده نکنید ,هیچگاه جنگو برای شما در دیتابیس نمیتواند رکوردی را ذخیره کند .همچنین مهم است که *args و **kwargs را درون ارگومان های ارسالی قرار دهید . این بخاطر این است که جنگو به صورت اتوماتیک هرازچندگاهی یک سری از ارگومان ها را به برنامه اضافه میکند و با این روش میتوان مطمین شد که کد شما در آینده نیز میتواند از آنها پشتیبانی کند .اگر می خواهید مقدار یک فیلد را در متد ()save به روز رسانی کنید ,شما میتوانید برای اطمینان حاصل کردن از اینکه عملیات به درستی انجام خواهد شد , از update_fields به صورت یک kwargs برای ارگومان ارسالی استفاده کنید . به مثال زیر نگاه کنید :from django.db import models from django.utils.text import slugify class Blog(models.Model): name = models.CharField(max_length=100) slug = models.TextField() def save( self, force_insert=False, force_update=False, using=None, update_fields=None ): self.slug = slugify(self.name) if update_fields is not None and &quotname&quot in update_fields: update_fields = {&quotslug&quot}.union(update_fields) super().save( force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields, )در باقی مسیر بیشتر درباره این موضوع صحبت خواهیم کرد .نکته : متد های بازنویسی شده مدل ها ,برای انجام عملیات هایی که روی چندین شی انجام می شوند (به اصطلاح اشیا انبوه) کار نمیکنند . در این مواقع باید از pre_save یا post_save استفاده کنید . اگر متوجه منظور این مطلب نمی شوید مشکلی ندارد . در ادامه مسیر درباره این متد ها توضیح خواهیم داد .در این جلسه به بررسی متد ها در مدل های جنگویی پرداختیم. در جلسه بعدی به بررسی ارث بری در مدل ها خواهیم پرداخت که بسیار مبحث طولانی ای خواهد بود .