?Django learn
?Django learn
خواندن ۱۱ دقیقه·۱ سال پیش

آموزش جنگو : جلسه سی و هفت | بررسی Field API در جنگو

در این جلسه در رابطه با api مربوط به فیلد ها در جنگو صحبت خواهیم کرد و چگونگی عملکرد فیلد ها در جنگو را بررسی می کنیم . با ما همراه باشید .

آموزش جنگو : جلسه سی و هفت | بررسی Field API در جنگو
آموزش جنگو : جلسه سی و هفت | بررسی Field API در جنگو


بررسی API فیلد

این بخش درباره API مربوط به فیلد ها است . یعنی قرار است متد های داخلی و فرایند عملکرد یک فیلد را با هم بررسی کنیم . همچنین بررسی می کنیم که یک فیلد دقیقا چیست . این مباحث مربوط به امور پیشرفته جنگو است . پس اگر هنوز مرحله مقدماتی هستید ,نیازی به بررسی این بخش نخواهید داشت .

در بخش های پیشین انواع فیلد ها را بررسی کرده بودیم . فیلد یک کلاس نوع abstract است که ستون های جدول دیتابیس را نشان می دهد . جنگو از فیلد ها (متد های درون کلاس آنها) برای ایجاد ساختار جدول دیتابیس (متد db_type) ,برای تبدیل نوع داده ای پایتون به نوع های درون دیتابیس (متد get_prep_value) و بالعکس (متد from_db_value) استفاده می کند .

بنابراین فیلد یک قطعه اساسی است که از API های مختلف جنگو بهره برده است .

در مدل ها یک فیلد به عنوان یک attribute یا ویژگی در کلاس تعریف می شود و در دیتابیس یک ستون خاص را نشون میدهد . همچنین مقادیری مانند null یا unique یا متد هایی را قبول می کند که باعث خاص شدن رفتار های فیلد (مثلا بتواند مقادیر خالی را بپذیرد) می شوند .

یک فیلد یک زیر کلاس از کلاس RegisterLookupMixin است . این علتی است که شما می توانید Lookup و Transform را روی آن پیاده سازی کنید (برای مثال field_name__exact="foo") .

همچنین علاوه بر فیلد های پیش فرض جنگو (مثلا JSONField یا CharField) می توانید بر اساس نیازتان فیلد های جدیدی را بسازید و از آنها استفاده کنید . بعدا درباره این کار توضیحاتی را ارائه خواهیم کرد . فعلا به بررسی کلاس ها و متد های درون یک فیلد خواهیم پرداخت . (از اینها بعدا در ساخت فیلد های custom استفاده می توانید کنید)

1-آرگومان description :یک توضیح مفصل درباره فیلد را می توانید در آن تعریف کنید . برای مثال در django.contrib.admindocs استفاده می شود .

یک Description می تواند به شکل زیر تعریف شود :

description = _(&quotString (up to %(max_length)s)&quot)

آرگومان های کد بالا نیز از __dict__ در فیلد پیدا و جایگذاری خواهند شد (مثل ویژگی max_length) .


2-آرگومان descriptor_class :کلاسی که descriptor protocol(از مباحث پایتون است) را برای کلاس شما تنظیم می کند . این کلاس نمونه سازی (instantiated) می شود و به ویژگی های شی افزوده می شود . البته سازنده یک آرگومان که شی Field است را باید قبول کند . بازنویسی این ویژگی می تواند به بازنویسی رفتار های get و set کلاس کمک کند .


جنگو برای تبدیل نوع های داده ای میان پایتون و دیتابیس چندین متد را ارائه می کند :

3-متد get_internal_type :این متد رشته ای را می سازد که فیلد شما را برای عملکرد های پشت صحنه (داخلی) جنگو نامگذاری کرده است . به طور پیش فرض نام کلاس را بازمی گرداند . (در مبحث شبیه سازی فیلد های پیش فرض برای استفاده در فیلد های سفارشی این مورد را استفاده می کنیم)


4-متد db_type(connection) :این متد با در نظر گرفتن connection یا بهتر بگوییم وابسته به دیتابیسی که استفاده می کنید , نوع داده ای ستون دیتابیس (فیلد) را بازمیگرداند . (در مبحث انواع داده های خاص برای فیلد های سفارشی این مورد را استفاده می کنیم)


5-متد rel_db_type(connection) : این متد با در نظر گرفتن connection یا بهتر بگوییم وابسته به دیتابیسی که استفاده می کنید , نوع داده ای فیلد را (فیلدهایی مانند OneToOneField یا ForeignKey) بازمیگرداند .

(در مبحث انواع داده های خاص برای فیلد های سفارشی این مورد را استفاده می کنیم) .

در اصل سه موقعیت اصلی وجود دارد که جنگو نیاز دارد تا ارتباطی را میان فیلد ها و دیتابیس برقرار کند . یعنی داده ها را میان آنها جا به جا کند تا اتفاقی رخ دهد . این سه موقعیت عبارتند از :

  • هنگامی که یک Query اجرا می کند (داده ها از پایتون به دیتابیس ارسال می شوند)
  • هنگامی که از دیتابیس داده ای را بازمیگرداند (داده ها از دیتابیس به پایتون ارسال می شوند)
  • هنگامی که چیزی را در دیتابیس ذخیره می کند (داده ها از پایتون به دیتابیس ارسال می شوند)

در هنگام اجرای Query دو متد get_db_prep_value و get_prep_value استفاده می شوند .


6-متد get_prep_value(value) :تعریف value در اینجا مقدار کنونی آن ویژگی مدل (فیلد) است و این متد داده ها را در قالبی که برای استفاده در Query (به عنوان پارامتر) آماده شده اند ,بازمیگرداند . (در مبحث تبدیل اشیا پایتونی به مقادیر Query این مورد را استفاده می کنیم) .

نکته : همگی مباحث جلوتر توضیح استفاده خواهند شد و از این متد ها برای ساخت فیلد های شخصی سازی شده یا custom استفاده می کنیم .


7-متد get_db_prep_value(value , connection , prepared=False) :نوع مقادیر یک Query با نوع مقادیر درون دیتابیس ها تفاوت دارند . این در صورتی است که مقدار های آنها کاملا یکسان است ! این متد نوع مقدار یک Query را به نوع مقداری که در دیتابیس وجود دارد تبدیل می کند . به طور پیش فرض اگر prepared=True باشد ,خود value یا مقدار را بازمیگرداند و در غیر این صورت متد get_prep_value را بازمیگرداند . (در مبحث تبدیل مقدار Query به مقادیر دیتابیس این مورد را استفاده می کنیم) .

هنگام لود کردن داده ها از دیتابیس متد from_db_value استفاده می شود .


8-متد from_db_value(value, expression, connection) :این متد مقداری که از دیتابیس لود شده است را تبدیل به یک شی پایتون می کند . دقیقا برعکس کاری که get_prep_value انجام می دهد . درباره چندی از این متدها قبلتر صحبت کردیم . (در مبحث تبدیل مقادیر دیتابیس به مقادیر پایتون این مورد را استفاده می کنیم) .

البته این متد در بیشتر فیلد های داخلی (فیلد هایی که خود جنگو دارد) استفاده نمی شود زیرا خود موتور دیتابیس نوع صحیح داده ای برای پایتون را بازمیگرداند .

و اینکه آرگومان expression در واقع همان self است .

نکته : به دلایل عملکردی ، from_db_value در فیلدهایی که به آن نیاز ندارند (همه فیلدهای جنگو) استفاده نشده است . در نتیجه شما ممکن است در تعریف خود super را فراخوانی نکنید . در ذخیره شدن اشیا یا رکورد ها در دیتابیس نیز متد های pre_save و get_db_prep_save استفاده می شوند .


9-متد get_db_prep_save(value, connection) : این متد مانند get_db_prep_value است ,اما فقط زمانی فراخوانی می شود که داده ها نیاز به سیو شدن در دیتابیس دارند (اگر یادتان باشد سیو و ایجاد در جنگو با یک روش انجام می شوند) . به طور پیش فرض get_db_prep_value را بازمیگرداند .


10-متد pre_save(model_instance, add) :در این قسمت درباره متد pre_save صحبت خواهیم کرد و باید مراقب باشید که متد را با با سیگنال آن اشتباه نگیرید . این متد قبل از get_db_prep_save فراخوانی می شود تا مقدار یا value را برای ذخیره شدن آماده کند (برای مثال زمان اتوماتیک در جنگو که با DateField.auto_now تعریف می شود با این متد مقداردهی می شود) .

آرگومان model_instance در واقع شی ای را می پذیرد که فیلدی که باید مقداردهی شود , در آن قرار گرفته است. آرگومان add نیز نشان می دهد که آیا این شی برای اولین بار در دیتابیس قرار است ذخیره شود یا خیر .

این متد باید مقدار مناسب را با توجه به ویژگی های شی و مقدار model_instance برای فیلد بازگرداند . نام ویژگی به طور خودکار توسط Field اضافه خواهد شد و در self.attname قابل دسترسی است . (در مبحث پردازش داده قبل از ذخیره شدن این متد را استفاده می کنیم)

فیلد ها گاهی اوقات مقادیر خود را به نوع های متفاوتی دریافت می کنند . برای مثال از طریق فرم ها یا serialization (از serialization در یکی از فریمورک های مربوط به جنگو استفاده می شود) . حال بیایید متد های مربوط به این مباحث را نیز بررسی کنیم .


11-متد to_python(value) :یک value را به یک شی پایتونی تبدیل می کند . این دقیقا برعکس عملکرد متد value_to_string است و همچنین در تابع clean نیز از آن استفاده شده است . (در مبحث تبدیل مقادیر به اشیا پایتون از این متد استفاده می کنیم)

علاوه بر فرم ها و نحوه ذخیره سازی داده ,یک فیلد باید بداند که چگونه داده ها را serialize کند .

نکته : serialize مبحثی مربوط به فریمورک rest جنگو است . اگر هنوز آشنایی با این مباحث ندارید ,از این بخش رد شوید .


12-متد value_from_object(obj) :مقدار فیلد را با توجه به شی دریافت شده (آرگومان obj) بازمیگرداند . این متد اغلب توسط value_to_string استفاده می شود .


13-متد value_to_string : شی دریافت شده را به رشته تبدیل می کند . این فرایند برای serialization بسیار کاربردی است . (در مبحث تبدیل داده های فیلد برای serialization این مورد را استفاده خواهیم کرد)

هنگام استفاده از مدل فرم ها ,باید فیلد بداند که از کدام form field استفاده کند . برای این کار یک متد وجود دارد :


14- متد formfield(form_class=None, choices_form_class=None, **kwargs) : فیلد پیش فرض مناسب برای ModelForm را از django.forms.Field بازمیگرداند .

به طور پیش فرض اگر form_class و choices_form_class برابر با None باشد ,فیلد CharField را بازمیگرداند.

اگر هم فیلد دارای choices و choices_form_class باشد که مقداردهی نشده ,از یک فیلد TypedChoiceField استفاده می کند . (در مبحث تعیین فرم فیلد برای یک مدل فرم این مورد را استفاده خواهیم کرد)


15-متد deconstruct :یک تاپل حاوی 4 اطلاعات مهم برای ساختن دوباره فیلد را بازمیگرداند :

  • نام فیلد در مدل
  • مسیری که نوع فیلد در آن قرار دارد (برای مثال django.db.models.IntegerField)
  • یک لیست حاوی آرگومان های positional
  • یک دیکشنری از آرگومان های keyword

این متد باید به فیلد های قبل از 1.7 اضافه شود تا داده های آن با استفاده از Migrations منتقل شود .


ویژگی های فیلد (Field attributes)

هر فیلد علاوه بر متد هایی که دارد ,دارای یک سری از ویژگی های خاص نیز می باشد . این ویژگی ها امکان بررسی درونی رفتار آن را فراهم می کنند . زمانی که نیاز به نوشتن کدی دارید که به عملکرد یک فیلد بستگی دارد ، به جای بررسی شی از این ویژگی ها استفاده کنید . این ویژگی ها را می توان همراه با Model._meta API برای محدود کردن فیلد ها و یا گسترش آنها استفاده کرد . (یعنی فیلد های سفارشی جدید ایجاد کرد)

1-ویژگی Field.auto_created : یک Boolean که نشان می دهد آیا فیلد به طور خودکار ایجاد شده است یا خیر. فیلدهایی مانند OneToOneField ایجاد شده توسط وراثت مدل مقدار True را برای این ویژگی دارند .


2-ویژگی Field.concrete :یک Boolean که نشان می دهد آیا ستونی در جدول دیتابیس با این فیلد مرتبط است (رابطه ایجاد شده است ,برای مثال رابطه OneToOne) یا خیر .


3-ویژگی Field.hidden :یک Boolean که نشان می دهد آیا از یک فیلد در عملکرد یک فیلد دیگر (که non-hidden است) استفاده می شود یا خیر . برای مثال ,فیلد های content_type و object_id که یک GenericForeignKey را تشکیل می دهند . این ویژگی برای تشخیص زیرمجموعه ای از فیلدها نیز به کار می رود.

نکته : متد Options.get_fields به طور پیش فرض فیلدهای hidden را exclude می کند . برای اینکه بتوانید فیلد های hidden را نیز در این متد استفاده کنید , include_hidden=True را درون متد استفاده کنید .


4-ویژگی Field.is_relation :یک Boolean است که نشان می دهد آیا یک فیلد حاوی ارجاعات روابطی به فیلد یا مدل های دیگر است یا خیر . برای مثال حاوی ForeignKey یا ManyToManyField یا OneToOneField یا …


5-ویژگی Field.model :مدلی را بازمیگرداند که حاوی فیلد شماست . اگر فیلد در یک superclass از مدل ساخته شده باشد,این ویژگی به superclass اشاره خواهد کرد و نه به کلاسی که شی دارد .

علاوه بر تمام اینها هر فیلد ویژگی هایی را نیز برای روابط خود دارد . این ویژگی ها برای ذخیره جزییات یک رابطه وجود دارند . این ویژگی ها در تمام فیلد ها نیز وجود دارد . اگر فیلد از نوع رابطه ای باشد (مانند OneToOneField) آنها فقط مقادیر Boolean را بجای None خواهند داشت .

1-ویژگی Field.many_to_many :اگر فیلد دارای یک رابطه چند به چند (many to many) باشد ,برابر با True خواهد بود . در غیر این صورت برابر با False خواهد بود . تنها فیلد موجود در جنگو که در آن این ویژگی برابر با True است ManyToManyField است .


2-ویژگی Field.many_to_one : اگر فیلد دارای یک رابطه چند به یک (many to one) باشد ,برابر با Trueخواهد بود . در غیر این صورت برابر با False خواهد بود . تنها فیلد موجود در جنگو که در آن این ویژگی برابر با True است ForeignKey است.


3-ویژگی Field.one_to_many :اگر فیلد دارای یک رابطه یک به چند (one to many) باشد ,برابر با True خواهد بود . در غیر این صورت برابر با False خواهد بود . تنها فیلدهای موجود در جنگو که در آن این ویژگی برابر با True است ForeignKey معکوس یا GenericRelation است.


4-ویژگی Field.one_to_one : اگر فیلد دارای یک رابطه یک به یک (one to one) باشد ,برابر با True خواهد بود. در غیر این صورت برابر با False خواهد بود . تنها فیلد موجود در جنگو که در آن این ویژگی برابر با True است OneToOneField است .


5-ویژگی Field.related_model :به مدلی اشاره می کند که فیلد به آن رابطه ای ایجاد کرده است . برای مثال مدل Author در ForeignKey(Author, on_delete=models.CASCADE) . همچنین همیشه برای یک GenericForeignKey ,مقدار related_model برابر با None است .


6-ویژگی Field.is_relation :این ویژگی نشان می دهد که آیا یک فیلد از نوع رابطه ای است یا خیر . فیلد های رابطه ای شامل ForeignKey , ManyToManyFieldو OneToOneField هستند . اگر فیلد از نوع رابطه ای باشد برابر با Trueقرار داده می شود .


در این جلسه نحوه عملکرد و مدیریت یک فیلد در جنگو را بررسی کردیم و تمامی ویژگی های یک فیلد در بک اند جنگو را دیدیم . در جلسه بعدی به بررسی api لوکاپ ها خواهیم پرداخت .

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