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

در این جلسه به بررسی تمامی فیلد های روابطی در جنگو خواهیم پرداخت . با ما همراه باشید .آموزش جنگو : جلسه بیست و چهار | انواع فیلدها | بخش دومفیلد ها : فیلد های روابطیجنگو سه فیلد برای روابط دیتابیسی برای شما قرار داده است که در ادامه به بررسی آنها به طور دقیق و کامل خواهیم پرداخت .فیلد ها : فیلد Foreignkeyیک رابطه چند به یک است . برای مثال این فیلد را را در دسته بندی ها استفاده می کنیم (هر پست می تواند یک دسته بندی داشته باشد ولی هر دسته بندی میتواند متعلق به چند پست باشد) .دو آرگومان را دریافت می کند ; ابتدا مدلی که به آن ربط می خواهید پیدا کنید و دوم گزینه on_delete است .نکته : برای ایجاد یک رابطه ForiegnKey به خود مدل (رابطه بازگشتی) از کد زیر میتوانید استفاده کنید .Models.ForeignKey(‘self’ , on_delete=models.CASCADE)اگر نیاز به ایجاد یک رابطه با مدلی دارید که هنوز ایجاد نشده است ,میتوانید از نام مدل به جای خود شی مدل استفاده کنید . به مثال زیر دقت کنید .from django.db import models class Car(models.Model): manufacturer = models.ForeignKey( 'Manufacturer', on_delete=models.CASCADE, ) # ... class Manufacturer(models.Model): # ... passنکته : برای ایجاد یک رابطه ForiegnKey به مدل هایی در اپ های دیگر باید به صراحت در یک رشته نام اپ و مدل خود را صدا بزنید . برای مثال برای ارجاع دادن (ایجاد رابطه) با مدل Manufacturer در اپ production باید به صورت زیر اقدام کنید .class Car(models.Model): manufacturer = models.ForeignKey( 'production.Manufacturer', on_delete=models.CASCADE, )این نوع از ارجاع که رابطه تنبل یا lazy شناخته می شود ,راه حل ارور circle import در پایتون است که هنگامی که دو اپ از یکدیگر import کنند ,ایجاد می شود .نکته :هنگامی که یک فیلد ForeignKey ایجاد می کنید ,جنگو به طور اتوماتیک db_index را روی True قرار می دهد.شما می توانید این ویژگی را با تعیین دوباره آن غیرفعال کنید .همچنین به یاد داشته باشید که کلمه “id_”به بعد از نام فیلد به صورت اتوماتیک اضافه خواهد شد (در دیتابیس نام ستون اینگونه خواهد بود). برای مثال مدل Car دارای ستون manufacturer_id خواهد بود که البته با تعیین db_column می توانید آن را تغییر دهید ولی پیشنهاد می شود تا هیچ وقت از آن استفاده نکنید . (مگر اینکه بخواهید کدهای SQL سفارشی بنویسید)فیلد ها : آرگومان های ForeignKey1-آرگومان ابتدایی این فیلد و مهمترین آرگومان ممکن on_delete است . On_delete مقادیر مختلفی را دریافت میکند . آنها رفتار های SQL هستند برای تعیین اینکه زمانی که رکورد ارجاع داده شده حذف شود , قرار است چه اتفاقی برای آن فیلد بیافتد . برای مثال اگر آن را روی SET_NULL تنظیم کنید , وقتی شی ارجاع داده شده حذف شود مقدار null بجای آن روی فیلد شما که به آن ارجاع پیدا کرده است , تنظیم می شود . (رایج ترین آنها CASCADE است)به مثال زیر برای متن بالا دقت کنید .user = models.ForeignKey( User, models.SET_NULL, blank=True, null=True, )مقادیر زیر برای این آرگومان قابل استفاده هستند .مقدار CASCADE :به زبانی ساده یعنی حذف کردن کل آبشار (آبشار یعنی اینکه شی ها زیر دسته همدیگر شده باشند) . این گزینه هنگامی که شی ارجاع داده شده حذف شود , شی حاوی ForeignKey را حذف خواهد کرد .این گزینه به وسیله سیگنال های pre_delete و post_delete کار خود را انجام خواهد داد .مقدار PROTECT :یک ارور ProtectedErrorبه شما نمایش داده می شود و از حذف کردن شی ارجاع شده جلوگیری می کند .مقدار RESTRICT :یک ارور RestrictedError به شما نمایش داده می شود و از حذف شی ارجاع شده جلوگیری می کند .بر خلاف PROTECT حذف شی ارجاع داده شده در صورتی ممکن است که در مدل شما یک رابطه با فیلدی دیگر از مدلی دیگر باشد که on_delete برای آن روی CASCADE تنظیم شده است . به یاد داشته باشید باید آنها در یک زمان حتما انجام بشوند . به مثال زیر نگاه کنید .class Artist(models.Model): name = models.CharField(max_length=10) class Album(models.Model): artist = models.ForeignKey(Artist, on_delete=models.CASCADE) class Song(models.Model): artist = models.ForeignKey(Artist, on_delete=models.CASCADE) album = models.ForeignKey(Album, on_delete=models.RESTRICT)حال در اینجا Artist می تواند حذف شود حتی اگر آلبومی که به یک Song ربط دارد خواننده را نیز دارا باشد . زیرا Song از طریق یک رابطه CASCADE به Artist ارجاع داده شده است . مثال :>>> artist_one = Artist.objects.create(name='artist one') >>> artist_two = Artist.objects.create(name='artist two') >>> album_one = Album.objects.create(artist=artist_one) >>> album_two = Album.objects.create(artist=artist_two) >>> song_one = Song.objects.create(artist=artist_one, album=album_one) >>> song_two = Song.objects.create(artist=artist_one, album=album_two) >>> album_one.delete() # Raises RestrictedError. >>> artist_two.delete() # Raises RestrictedError. >>> artist_one.delete() (4, {'Song': 2, 'Album': 1, 'Artist': 1})مقدار SET_NULL :اگر شی ارجاع داده شده حذف شود , مقدار null روی فیلد شما تنظیم می شود . (باید null=True قرار داده شود )مقدار SET_DEFAULT :اگر شی ارجاع داده شده حذف شود ,مقدار default فیلد روی آن تنظیم می شود . (باید مقدار defautl برای آن تعیین شود)مقدار SET :مقدار فیلد را پس از حذف شدن شی ارجاع داده شده روی مقدار داده شده به این تابع تنظیم می کند . در بعضی موارد در هنگام import کردن فایل models.py , نیاز است که یک تابع که مقداری را باز میگرداند در SET قرار داده شود . به مثال زیر دقت کنید که چگونه یک تابع را در SET تنظیم کرده ایم .from django.conf import settings from django.contrib.auth import get_user_model from django.db import models def get_sentinel_user(): return get_user_model().objects.get_or_create(username='deleted')[0] class MyModel(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user), )مقدار DO_NOTHING :هیچ کاری انجام نمی دهد . گرچه این مورد در بعضی از دیتابیس ها پشتیبانی نمی شود و باعث یک IntegrityError می شود . مگر اینکه برای این موارد به صورت دستی در دیتابیس SQL ON DELETE را مشخص کنید .2-آرگومان دوم این فیلد که اختیاری است limit_choices_to است . این مقدار یک dict یا دیکشنری را قبول میکند . علاوه بر دیکشنری ,میتوانید از Q (در جلوتر خواهید خواند) یا تابعی استفاده کرد که یک دیکشنری را باز گرداند . در دیکشنری باید فیلتر های خود را بر اساس فیلد های مدل ارجاع داده شده بنویسید . این به شما کمک می کند تا گزینه های قابل انتخاب در ModelForm یا ادمین پنل محدود شوند . (بر اساس فیلتر های شما) به مثال زیر نگاه کنید .staff_member = models.ForeignKey( User, on_delete=models.CASCADE, limit_choices_to={'is_staff': True}, )در مثال بالا فقط گزینه هایی نشان داده می شوند که is_staff آنها برابر با True باشد .شما همچنین مانند مثال بعدی در صفحه بعد از یک تابع که مقدار یک دیکشنری را به شما باز می گرداند استفاده کنید . در این مثال ما از فیلتر اشیا در یک بازه زمانی استفاده کرده ایم .def limit_pub_date_choices(): return {'pub_date__lte': datetime.date.today()} limit_choices_to = limit_pub_date_choicesنکته تخصصی : در شرایطی که شما به عنوان مقدار یک Q را به limit_choices_to بدهید ,فقط زمانی بر روی اشیا نشان داده شده در ادمین پنل تاثیر خواهد داشت که در ModelAdmin در فایل admin.py مقدار raw_id_fields تنظیم نباشد .توجه داشته باشید که توابعی مانند مثال بالا هر بار که شی جدیدی ایجاد شود , اجرا خواهند شد تا مقدار گزینه ها را محدود کنند . همچنین ممکن است به وسیله اعتبارسنجی های اجرا شده در ادمین پنل این توابع دوباره یا چند بار اجرا شوند .3-آرگومان سوم related_name است . مقدار یک str یا رشته را قبول میکند . در واقع این همان نامی است که بعدا بجای نام اصلی فیلد قرار است استفاده شود . در بعد ها توضیح خواهیم داد که در چه مواردی باید از related_name استفاده کنیم . معمولا در رابطه های بازگشتی از مدل ارجاع داده شده به مدل اصلی حاوی فیلد یا هنگامی که چند Foreignkey داشته باشید ,استفاده می شود . همچنین در هنگام استفاده از مدل های abstract از این گزینه زیاد استفاده می شود و در مورد استفاده از آن قوانین و سینتکس های خاصی وجود دارد که بعدا در مورد آنها توضیح خواهیم داد .سخن نویسنده : بابت به هم ریختگی مطالب از شما عذر خواهی میکنیم . مطالب از وبسایت رسمی جنگو جمع اوری و ترجمه شده اند و ترتیب خاصی را دارا نمی باشند . بنابراین به خواندن ادامه بدهید . در آخر فصل همه چیز منطقی تر به نظر خواهد رسید :)گاهی باید related_name را روی فیلد خود تنظیم کنید . اما اگر بنا به دلایلی نمی خواهید این کار را انجام بدهید ,باید مقدار آن را روی + تنظیم کنید یا آن را با +خاتمه دهید . مثال زیر را نگاه کنید . در اینجا مدل User هرگز رابطه معکوس با مدل اصلی شما نخواهد داشت .user = models.ForeignKey( User, on_delete=models.CASCADE, related_name='+', )4-آرگومان چهارم نامی است که از آن برای reverse query یا query زدن برعکس از مدل ارجاع داده شده به مدل اصلی استفاده می شود (فقط query). این نام به طور پیش فرض از روی مقدار related_name برداشته می شود و شما نیازی به تنظیم آن ندارید . اگر شما related_name را تنظیم نکرده باشید ,نام از روی نام مدل برداشته خواهد شد .همچنین این مورد نیز دارای سینتکس های خاصی می باشد . به مثال زیر دقت کنید :# Declare the ForeignKey with related_query_name class Tag(models.Model): article = models.ForeignKey( Article, on_delete=models.CASCADE, related_name=&quottags&quot, related_query_name=&quottag&quot, ) name = models.CharField(max_length=255) # That's now the name of the reverse filter Article.objects.filter(tag__name=&quotimportant&quot)5-آرگومان بعدی گزینه db_constraint است . این گزینه دو مقدار True یا False را قبول می کند . اگر برابر با True باشد , constraint یا محدودیت نوع داده ورودی بر روی فیلد در دیتابیس اعمال می شود . این یعنی فقط رشته ها یا فقط اعداد یا هر نوع یا الگوی خاصی را می تواند فیلد شما قبول کند . به طور پیش فرض برابر با True است و معمولا این گزینه دستکاری نمی شود ,اما شرایطی وجود دارد که در آن شما لازم دارید تا آن را روی False تنظیم کنید :-شما داده های قدیمی دارید که معتبر نیستند .-شما می خواهید دیتابیس خود را به اشتراک بگذارید .-اگر برابر با False قرار داده شود ,در تلاش برای دسترسی پیدا کردن به یک شی از مدل ارجاع داده شده به مدل اصلی (related) که وجود ندارد ,شما با ارور DoesNotExist مواجه می شوید .همانطور که گفتیم این ویژگی زیاد دستکاری نمی شود .6-آرگومان بعدی گزینه swappable است که دو مقدار True و False را می پذیرد . بعضی از مدل ها مانند User (مدل پیش فرض جنگو که برای کاربران ساخته شده است ,شما آن را از قبل می شناسید ) مدل های قابل تعویض نامیده می شوند . این یعنی شما می توانید در فایل settigns متغییری را تعریف کنید و در view با استفاده از تنظیمات فایل settings با آن مدل کار کنید . این گونه می توانید در هر زمان که نیاز دارید مدل پیش فرض را عوض کنید و از مدل جدیدی استفاده کنید (فقط با تغییر فایل settings.py) . برای User باید در فایل settings.py متغییر AUTH_USER_MODEL را تغییر دهید .حال این آرگومان مقدار migrate را اگر ForeignKey شما اشاره به مدلی قابل تعویض داشته باشد ,کنترل خواهد کرد . به طور پیش فرض برابر با True است . یعنی اگر مدل شما با مدلی که در فایل settings تنظیم کرده اید ,یکسان باشد (همان مدل قابل تعویض باشد) ,بجای اینکه migrate را در مدل به طور مستقیم ذخیره کند ,در فایل settings.py ذخیره خواهد کرد .اگر مطمئن هستید که مدل شما همیشه یک مدل قابل تعویض است ,میتوانید آن را روی False تنظیم کنید . برای مثال اگر مدل profile ای را ایجاد کنید که به مدل user سفارشی و شخصی سازی شده شما اشاره دارد . گرچه بهتر است مانند بالایی برابر با True قرار داده شود .فیلد ها : فیلد های ManyToManyیک رابطه چند به چند است . این فیلد را می توانید برای مثال در سیستم لایک کردن استفاده کنید . هر کاربر می تواند تعداد زیادی از پست ها را لایک کند و هر پست می تواند تعداد زیادی لایک داشته باشد . (یک فیلد ManyToMany در مدل پست است که به کاربران اشاره دارد و هر بار کاربری لایک کند ,کاربر به فیلد شما اضافه می شود . این روش برای مقابله با فریب سیستم و اینکه کاربران دو بار یک پست را لایک کنند مفید است ) . بعدا در پروژه فروشگاهی خود این مورد را استفاده می کنیم تا به طور کامل متوجه آن شوید .همچنین در نوع روابط مانند lazy یا روابط بازگشتی موارد یکسانی با ForeingKey دارد . (همچنین آرگومان های آن نیز بسیار مشابه است)فیلد ها : آرگومان های فیلد ManyToMany1-آرگومان ابتدایی آن related_name است . (یکسان با ForeignKey)2- آرگومان دوم این فیلد related_query_name است . (یکسان با ForeingKey)3-آرگومان سوم شما limit_choices_to است . (یکسان با ForeingKey)4-آرگومان چهارم شما symmetrical است . این آرگومان فقط زمانی استفاده می شود که فیلد شما به مدل خودش ارجاع داده شود . مدل زیر را در نظر بگیرید :from django.db import models class Person(models.Model): friends = models.ManyToManyField(&quotself&quot)وقتی جنگو این مدل را پردازش می کند مشخص می کند که یک رابطه ManyToMany با خودش دارد . در نتیجه ویژگی Person_set به این مدل اضافه نمی شود (در مورد این ویژگی بخوانید) . در عوض این فیلد متقارن فرض می شود . در داکیومنت جنگو نوشته شده است که این جمله یعنی اگر من دوست تو هستم ,تو نیز دوست من هستی !فقط به یاد داشته باشید اگر فیلد شما متقارن باشد و به خودش اشاره داشته باشد , شما نمی توانید از روابط معکوس یا همان روابط بازگشتی استفاده کنید (related) . اگر می خواهید حتما از این نوع روابط بهره ببرید بهتر است تا symmetrical را روی False قرار دهید . این کار جنگو را مجبور می کند تا descriptor را برای فیلد شما اضافه کند . همچنین اجازه می دهد تا روابط شما غیرمتقارن باشند .5-آرگومان بعدی through است . درک این آرگومان کمی مشکل است و ما درباره آن در قبل ها مثال هایی را زده ایم .فصل جدول های میانی درباره همین بوده است . جنگو برای ایجاد رابطه ManyToMany از یک جدول ایجاد شده به صورت اتوماتیک استفاده می کند . اگر می خواهید به صورت دستی این جدول را تعیین کنید ,آرگومان through را در فیلد قرار می دهید و مقدار آن را برابر با مدل خود قرار می دهید . از این پس آن مدل به عنوان مدل میانی استفاده خواهد شد .نکته : اگر هنوز متوجه نشده اید منظور ما چیست ,ما در گذشته در بخشی از مقالات به طور کامل این مبحث را توضیح داده ایم و اکنون به طور خلاصه آن را ادامه می دهیم .رایج ترین کاربرد این آرگومان زمانی است که می خواهید یک مدل میانی داشته باشید که اطلاعات اضافه درباره رابطه ManyToMany شما را در خود ذخیره کند .اگر به طور صریح مدل میانی را در through مشخص نکنید ,هنوز یک مدل به صورت اتوماتیک ایجاد شده است و شما از طریق آن می توانید به بررسی دیتابیس بپردازید . این مدل اتوماتیک ,سه فیلد دارد .اگر مدل ارجاع داده شده برابر با self نیست مدل میانی به صورت اتوماتیک ایجاد شده سه فیلد دارد :-فیلد id : یک فیلد برای ذخیره سازی id(همان primary key است و کنترل آن دست شما نیست)-فیلد id of containing model :یک فیلد برای ذخیره سازی idمدلی که حاوی ManyToManyField است .-فیلد id of other model :یک فیلد برای ذخیره سازی id مدلی که مدل قبلی شما به آن ارجاع داده شده است .اگر مدل ارجاع داده شده برابر با self باشد مدل میانی به صورت اتوماتیک ایجاد شده سه فیلد دارد :-فیلد id : یک فیلد برای ذخیره سازی id(همان primary key است و کنترل آن دست شما نیست)-فیلد from model id :یک فیلد برای ذخیره سازی idشی یا رکورد یا نمونه ای که حاوی فیلد شماست .-فیلد to model id :یک فیلد برای ذخیره سازی id شی یا رکورد یا نمونه ای که فیلد شما با آن رابطه دارد . (منظور id نمونه های انتخاب شده در فیلد است)این کلاس می تواند به صورت یک مدل معمولی برای query یا جستجو در رکورد های مرتبط با یک نمونه مدل استفاده شود.Model.m2mfield.through.objects.all()6-آرگومان بعدی thruogh_fields است . این آرگومان فقط زمانی استفاده می شود که شما یک مدل میانی شخصی سازی شده دارید (یعنی خودتان مدل میانی را ایجاد کرده اید) . در این شرایط جنگو معمولا به صورت اتوماتیک تعیین می کند که از کدام فیلد های مدل میانی استفاده کند تا به طور خودکار یک رابطه چند به چند را ایجاد کند . با این حال مدل زیر را در نظر بگیرید .from django.db import models class Person(models.Model): name = models.CharField(max_length=50) class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField( Person, through='Membership', through_fields=('group', 'person'), ) class Membership(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) person = models.ForeignKey(Person, on_delete=models.CASCADE) inviter = models.ForeignKey( Person, on_delete=models.CASCADE, related_name=&quotmembership_invites&quot, ) invite_reason = models.CharField(max_length=64)در مثال بالا شما در مدل Membership دو فیلد foreignKey متصل به Person دارید . این دو فیلد باعث می شود تا جنگو در تشخیص اینکه کدام فیلد ها باید برای ایجاد رابطه استفاده شوند ,دچار مشکل شود . پس مانند مثال بالا باید برای فیلد ManyToMany آرگومان through_fields را نیز تعریف کنید و نام فیلد های group و person که در اینجا فیلد های برقرار کننده رابطه میان دو مدل هستند را به آن بدهید . (فیلد ForiengKey بعدی در واقع اطلاعات اضافه شماست و نباید در طرفین رابطه ManyToMany تاثیر خاصی ندارد)مقداری که این آرگومان قبول می کند یک تاپل دو عضوی است . برای مثال (‘field1’ , ‘field2’) که در آن field1 مدلی است که حاوی ManyToManyField است (در اینجا group) و field2 مدلی است که رابطه ManyToMany به آن ارجاع شده است . (در اینجا person)توجه داشته باشید این مورد زمانی استفاده می شود که بیش از دو ForeignKey در مدل میانی داشته باشید . همچنین در مورد روابط بازگشتی نیز صدق می کند .7-آرگومان هفتم db_table است . مقدار یک رشته را قبول میکند . در واقع نام جدول میانی ای است که جنگو برای ایجاد رابطه ManyToMany استفاده می کند (جدولی که اتوماتیک ایجاد می شود را به یاد دارید؟ ) . اگر این تعیین نشده باشد ,جنگو آن را از روی مقدار زیر استفاده می کند :نام جدولی که رابطه را درون خود دارد و نام خود فیلد .8-آرگومان db_constraint , آرگومان هشتم شماست . این گزینه دو مقدار True یا False را قبول می کند . اگر برابر با True باشد , constraint یا محدودیت نوع داده ورودی بر روی فیلد در دیتابیس اعمال می شود . این یعنی فقط رشته ها یا فقط اعداد یا هر نوع یا الگوی خاصی را می تواند فیلد شما قبول کند . به طور پیش فرض برابر با True است و معمولا این گزینه دستکاری نمی شود ,اما شرایطی وجود دارد که در آن شما لازم دارید تا آن را روی False تنظیم کنید :شما داده های قدیمی دارید که معتبر نیستند .شما می خواهید دیتابیس خود را به اشتراک بگذارید .نکته : استفاده از آن با آرگومان through به صورت همزمان باعث ارور خواهد شد .8-آرگومان بعدی swappable است که دو مقدار True و False را می پذیرد . بعضی از مدل ها مانند User (مدل پیش فرض جنگو که برای کاربران ساخته شده است ,شما آن را از قبل می شناسید ) مدل های قابل تعویض نامیده می شوند . این یعنی شما می توانید در فایل settigns متغییری را تعریف کنید و در view با استفاده از تنظیمات فایل settings با آن مدل کار کنید . این گونه می توانید در هر زمان که نیاز دارید مدل پیش فرض را عوض کنید و از مدل جدیدی استفاده کنید (فقط با تغییر فایل settings.py) . برای User باید در فایل settings.py متغییر AUTH_USER_MODEL را تغییر دهید .حال این آرگومان مقدار migrate را اگر ForeignKey شما اشاره به مدلی قابل تعویض داشته باشد ,کنترل خواهد کرد . به طور پیش فرض برابر با True است . یعنی اگر مدل شما با مدلی که در فایل settings تنظیم کرده اید, یکسان باشد (همان مدل قابل تعویض باشد) ,بجای اینکه migrate را در مدل به طور مستقیم ذخیره کند ,در فایل settings.py ذخیره خواهد کرد .اگر مطمئن هستید که مدل شما همیشه یک مدل قابل تعویض است ,میتوانید آن را روی False تنظیم کنید . برای مثال اگر مدل profile ای را ایجاد کنید که به مدل user سفارشی و شخصی سازی شده شما اشاره دارد .گرچه بهتر است مانند بالایی برابر با True قرار داده شود .نکته : فیلد ManyToManyField از validator ها پشتیبانی نمی کند . همچنین null نیز تاثیری بر روی این فیلد ندارد.فیلد ها : فیلد OneToOneFieldیک رابطه یک به یک است . این فیلد را می توانید برای مثال در سیستم پروفایل استفاده کنید . هر کاربر می تواند یک پروفایل داشته باشد و هر پروفایل متعلق به یک کاربر است . از نظر مفهومی در واقع همان ForeignKey است که unique آن برابر با True است . اما سمت معکوس آن مستقیما یک شی را باز میگرداند .استفاده از این فیلد یکی از بهترین راه ها به جای استفاده از primary Key است . ارث بری چندجدولی که از یک OneToOneField برای ارجاع پیدا کردن فرزند به کلاس پدر استفاده می کند , یکی از مثال های استفاده از آن به جای primary Key است .روابط معکوس یا همان استفاده از آرگومان هایی مانند related_name و یا روابط lazy در این فیلد مانند فیلد ForeignKey است و تفاوت چندانی در قوانین استفاده از آن ندارد .اگر شما از related_name استفاده نکنید و آن را تعیین نکنید ,جنگو به صورت پیش فرض با حروف کوچک نام فیلد شما را به عنوان related_name استفاده خواهد کرد .به کد زیر دقت کنید .from django.conf import settings from django.db import models class MySpecialUser(models.Model): user = models.OneToOneField( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, ) supervisor = models.OneToOneField( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='supervisor_of', )مدل User شما به صورت زیر خواهد بود .>>> user = User.objects.get(pk=1) >>> hasattr(user, 'myspecialuser') True >>> hasattr(user, 'supervisor_of‘) Trueنکته : تابع hasattr مربوط به بررسی attribute ها است و از مباحث پایتون است . (در اینجا آموزش داده نمی شود . در اینترنت بخوانید)اگر یکی از شی های رابطه بازگشتی یا related شما به شی ای اشاره کند که وجود ندارد (یعنی جستجوی related شما وجود نداشته باشد ) به شما ارور RelatedObjectDoesNotExist بازگردانده می شود .حال به مثال زیر دقت کنید . اگر یک user یا کاربر تولید شده از مدل MySpecialUser مقدار supervisor را نداشته باشد (یعنی مقدار attribute یا ویژگی آن را به طریقی حذف کنید تا آن را دارا نباشد) :try: user.supervisor_of except User.supervisor_of.RelatedObjectDoesNotExist: passفیلد ها : آرگومان های OneToOneFieldبه یاد داشته باشید که فیلد OneToOneField تمام آرگومان های فیلد ForeignKey را می پذیرد . علاوه بر آنها یک آرگومان اضافی برای این فیلد وجود دارد .1-آرگومان اضافی آن parent_link است . این آرگومان فقط در زمانی استفاده می شود که مدل شما باید از یک مدل دیگر ارث بری کند . در صورت قرار دادن آن برابر با True ,فیلد شما به عنوان پیوند میان کلاس فرزند و والد استفاده می شود . به جای OneToOneField اضافی که به صورت ضمنی و با کلاس بندی فرعی ایجاد می شود , این را میتوانید استفاده کنید . (داکیومنت جنگو در مورد این آرگومان همین مقدار توضیح داده بود . برای اطلاعات بیشتر کمی در گوگل تحقیق کنید )در این جلسه به بررسی کامل فیلد های روابطی در جنگو پرداختیم . در جلسه بعدی به مبحث ایندکس ها (index) در دیتابیس ها و جنگو میپردازیم .