آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

ارث بری در جنگو

آموزش Django

آموزش ارث بری در مدل با Django



میتوان گفت عملکرد وراثت در Django عینا همانند عملکرد وراثت در کلاس های معمولی پایتون است، اما اصول اولیه در ابتدای صفحه همچنان باید رعایت شود، به معنی که base class همچنان بایدsubclass ، django.db.models.Model را دارا باشد.


انتخاب اینکه آیا مدل های parent، مدل هایی با اختیارات خاص خود باشند( جداول دیتابیس خاص خودرا دارا باشند) و یا اینکه parents تنها نگهدارنده هایی برای اطلاعات مشترکی باشند که تنها از طریق مدل های child قابل مشاهده است، باشماست.


وراثت به سه شکل در Django ممکن ست:



  • گاهی ممکن است بخواهید از کلاس parent برای نگهداری اطلاعات استفاده کنید تا نیازی به تکرار آن اطلاعات در هر کلاس child نداشته باشید. در این حالت، این کلاس هرگز به تنهایی استفاده نخواهد شد و میتوانید از کلاس انتزاعی پایه استفاده کنید.

  • اگر شما از subclass یک مدل موجود( که حتی میتواند مطعلق به یک اپلیکیشن متفاوت باشد) استفاده میکنید، و میخواهید هر مدل دارای جداول دیتابیس مخصوص به خود باشد، استفاده از وراثت چند جدولی برای شما توصیه میشود.

  • در نهایت اگر فقط میخواهید عملکرد مدل در سطح پایتون را تغییر دهید و میخواهید فیلد های مدل دست نخورده باقی بمانند، میتوانید از مدل های پروکسی ، استفاده کنید.

کلاس های انتزاعی پایه ( abstract base class) در Django




کلاس های انتزاعی پایه زمانی مفیدند که بخواهید اطلاعات مشترکی را در تعدادی مدل دیگر قرار دهید. شما میتوانید کلاس پایه خود را بنویسید و در کلاس meta ، abstract = True قرار دهید. به این ترتیب، این مدل برای ایجاد هیچ جدولی در دیتابیس استفاده نمیشود. اما به عنوان کلاس پایه برای مدل های دیگر استفاده شده و فیلد های آن به فیلد های کلاس های child اضافه خواهد شد.

برای مثال:



                from django.db import models

                class CommonInfo(models.Model):
                    name = models.CharField(max_length=100)
                    age = models.PositiveIntegerField()

                    class Meta:
                        abstract = True

                class Student(CommonInfo):
                    home_group = models.CharField(max_length=5)
                


مدل Student دارای سه فیلد خواهد بود: name، age و home_group . مدلCommonInfo ، از آنجا که یک کلاس انتزاعی پایه است، نمیتواند به عنوان یک مدل معمول Django استفاده شود. همچنین نمیتواند جداول دیتابیس ایجاد کند ، دارای manager باشد و یا به طور مستقیم نمونه سازی و یا ذخیره شود.


فیلد هایی که از کلاس های پایه انتزاعی منتقل میشوند را میتوان با یک فیلد ویا یک مقدار جدید override کرد و یا با None به طور کلی حذف کرد.


وراثت مدل ها به این شکل، برای اکثر کاربرد ها مناسب است و روشی را فراهم میکند که اطلاعات مشترک را در سطح پایتون فاکتور گرفت و تنها یک جدول دیتابیس برای هر مدل child در سطح دیتابیس ایجاد کرد.


وراثت meta در Django



زمانی که یک کلاس انتزاعی پایه ایجاد میشود، Django هر meta class داخلی را که شما تعریف کرده باشید، به عنوان یک صفت در base class دردسترس قرار میدهد. اگر یکchild class ، meta class خود را تعریف نکند، آن را از parent خود به ارث میبرد. اگر child بخواهد meta class را از parent خود extent کند، میتوان آن را به عنوان subclass در نظر بگیرد. برای مثال:


                from django.db import models

                class CommonInfo(models.Model):
                    # ...
                    class Meta:
                        abstract = True
                        ordering = ['name']

                class Student(CommonInfo):
                    # ...
                    class Meta(CommonInfo.Meta):
                        db_table = 'student_info'
                


Django برای یک کلاس انتزاعی پایه، یک meta class تنظیم میکند: پیش از نصب صفت meta، abstract = False قرار میده و این بدین معنی است که child های یک کلاس انتزاعی پایه، به شکل اتوماتیک تبدیل به کلاس انتزاعی نمیشوند. برای ساخت یک کلاس انتزاعی پایه که با وراثت از یک کلاس انتزاعی پایه دیگر ساخته شده، باید صریحا برایchild ها abstract را برابر True قرار دهید.


برخی از صفات برای قرار دادن در meta class یک کلاس انتزاعی پایه، مناسب نیستند. برای مثال قرار دادن db_table در meta class به این معنی است که تمام child class ها ( آنهایی که meta خود را تعریف نکرده اند) از این جداول دیتابیس استفاده میکنند، که احتمالا برای شما مفید نخواهد بود.


بنابر سیستم وراثت پایتون، اگر یک child class وراثتی از چند کلاس انتزاعی پایه داشته باشد، به صورت پیش فرض، تنها گزینه های meta از کلاسی که اول لیست شده را به ارث خواهد برد. برای به ارث بردن گزینه های meta از چند کلاس انتزاعی پایه، باید صراحتا وراثت meta را مشخص کنید.


برای مثال:


                from django.db import models

                class CommonInfo(models.Model):
                    name = models.CharField(max_length=100)
                    age = models.PositiveIntegerField()

                    class Meta:
                        abstract = True
                        ordering = ['name']

                class Unmanaged(models.Model):
                    class Meta:
                        abstract = True
                        managed = False

                class Student(CommonInfo, Unmanaged):
                    home_group = models.CharField(max_length=5)

                    class Meta(CommonInfo.Meta, Unmanaged.Meta):
                        pass
                

مراقب related_name و related_query_name باشید


اگر از related_name و یا related_query_name در یک foriegnKey و یا ManyToManyFiled استفاده میکنی، باید همواره یک نام reverse یکتا و یک نام query برای فیلد انتخاب کنید. این کار معمولا برای کلاس های انتزاعی پایه مشکل ایجاد میکند، زیرا که فیلد های این کلاس در هریک از child class های آن، با همان مقادیر و صفت ها ( از جمله related_name و related_query_name ) وجود دارند.


برای حل این مشکل، زمانی که از related_name و یا related_query_name در(فقط) یک کلاس انتزاعی پایه استفاده میکنی، بخشی از مقدار آن باید شامل ‘%(app_label)s’ و ‘%(class)s’ باشد.


  • ‘%(class)s’ به جای نام child class ی که فیلد در آن استفاده شده است، با حروف کوچک ، قرار میگیرد.

  • ‘%(app_label)s’ به جای نام اپلیکیشنی که child class را شامل میشود، با حروف کوچک، قرار میگیرد. نام هر اپلیکیشن نصب شده باید یکتا باشد و نام modelهای class ها در هر اپلیکیشن نیز باید یکتا باشد، در نتیجه، ترکیب این نام ها متفاوت خواهد بود.

برای مثال برای اپلیکیشن common/models.py :


                from django.db import models

                class Base(models.Model):
                    m2m = models.ManyToManyField(
                        OtherModel,
                        related_name="%(app_label)s_%(class)s_related",
                        related_query_name="%(app_label)s_%(class)ss",
                    )

                    class Meta:
                        abstract = True

                class ChildA(Base):
                    pass

                class ChildB(Base):
                    pass
                


و یک اپلیکیشن دیگر rare/models.py :



                from common.models import Base

                class ChildB(Base):
                    pass
                

نام reverse برای فیلد common.ChildA.m2m، common_childa_related و نام reverse query، common_chilas خواهد بود. نام reverse برای فیلد common.ChildB.m2m، common_childb_related و نام reverse query آن ، common_childbs خواهد بود. و درنهایت نام reverse برای فیلد rare_childB.m2m، rare_childb_related و نام revers query آن، rare_childbs است.روش و میزان استفاده از ‘%(class)s’ و ‘%(app_label)s’ برای ساخت related name و related query name هایتان به عهده شما خواهد بود، اما اگر از آنها استفاده نکنید، Django در زمان اجرای system check ( اجرای migrate)، Error ایجاد خواهد کرد.


اگر برای یک فیلد در یک کلاس انتزاعی پایه ، صفت related_name اختصاص ندهید، نام reverse به صورت پیش فرض، نام child class به همراه ‘_set’ خواهد بود، مانند زمانی که فیلد را مستقیما در child class تعریف میکنید. برای مثال، در کد بالا، اگر صفت related_name حذف شود، نام reverse برای فیلد m2m، childa_set برای ChildA و childb_set برای فیلد ChildB خواهد بود.



وراثت چند جدولی در Django



دومین نوع وراث در مدل که در Django پشتیبانی میشود، زمانی است که هر مدل در سلسله مراتب، به تنهایی یک مدل است. هر مدل در ارتباط با جداول دیتابیس خود است و میتواند به تنهایی آنها را ایجاد کند و بر آنها کوئری بزند. رابطه وراثت باعث میشود بین مدل های child و مدل های parent ارتباط (link) ایجاد شود( به وسیله ی OneToOneFiled که به شکل اتوماتیک ایجاد میشود). برای مثال:


                from django.db import models

                class Place(models.Model):
                    name = models.CharField(max_length=50)
                    address = models.CharField(max_length=80)

               class Restaurant(Place):
                   serves_hot_dogs = models.BooleanField(default=False)
                   serves_pizza = models.BooleanField(default=False)
                

تمام فیلد های Place در Restaurant نیز در دسترس است، اما داده ها در جداول مختلفی قرار میگیرند. در نتیجه هر دو این مثال ها امکان پذیرند:


                >>> Place.objects.filter(name="Bob's Cafe")
                >>> Restaurant.objects.filter(name="Bob's Cafe")
                

اگر شما یک Place داشته باشید که یک Restaurant هم باشد، میتوانید از طریق شی Place، با استفاده از نام مدل با حروف کوچک، به شی Restaurant دسترسی داشته باشید:


                >>> p = Place.objects.get(id=12)
                # If p is a Restaurant object, this will give the child class:
                >>> p.restaurant
                
                

اما اگر p، در مثال بالا یک Restaurant نباشد( مستقیما به عنوان یک شی place معرفی شده باشد و یا parent یک کلاس دیگر باشد)، اشاره به p.restaurant باعث ایجاد تناقض Restaurant.DoesNotExist میشود.


OneToOneFiled که به شکل اتوماتیک در Restaurant ایجاد میشود و به Place لینک داده میشود، مانند زیر است:


               place_ptr = models.OneToOneField(
                   Place, on_delete=models.CASCADE,parent_link=True,
                   primary_key=True,
               )
                

شما میتوانید با ایجاد OneToOneFiled خود، با قرار دادن parent_link=True در Restaurant، این فیلد را override کنید.



وراثت meta و چند جدولی



در شرایط وراثت چند جدولی، برای یکchild class منطقی نیست که از meta class، parent خود وراثتی داشته باشد زیرا که تمام گزینه های meta در parent class، اعمال شده اند و اعمال دوباره آنها باعث عملکرد غیر معمول میشود( این قضیه با کلاس انتزاعی پایه متفاوت است زیرا که کلاس انتزاعی پایه به خودی خود وجود ندارد).


بنابر این مدل child به meta class، parent خود دسترسی ندارد. اما، شرایط محدودی وجود دارد که درآن شرایط یک child class میتواند عملکردی را از parent خود به ارث ببرد: اگر child صفت ordering مشخص و یا صفت get_latest_by نداشته باشد، آنها را از parent خود به ارث میبرد.


اگر parent دارای ordering است اما نمیخواهید child دارای ordering باشد، میتوانید آن را غیر فعال کنید:


                class ChildModel(ParentModel):
                    # ...
                class Meta:
                    # Remove parent's ordering effect
                    ordering = []
                


وراثت و روابط معکوس (reverse relationships)



از آنجایی که وراثت چند جدولی، صریحا از OneToOneFiled برای ایجاد ارتباط بین child و parent استفاده میکند، میتوان از بالا به پایین از parent به child آن، مانند مثال بالا، منتقل شد. اما باید از مقدار related_name برای foreignKey و ورابط ManyToManyFiled استفاده کرد. اگر بخواهید این نوع روابط را بر یک subclass از یک مدل parent قرار دهید، باید صفت related_name را برای هر فیلد مشخص کنید. در غیر این صورت Django با validation error روبرو خواهد شد.


برای مثال، با استفاده از مثال Place بالا، میتوان subclass دیگری به وسیله ی ManyToManyFiled ایجاد کرد:


                class Supplier(Place):
                customers = models.ManyToManyField(Place)
                

این کار باعث ایجاد میشود:


                 Reverse query name for 'Supplier.customers' clashes with reverse query
                 name for 'Supplier.place_ptr'.

                 HINT: Add or change a related_name argument to the definition for
                 'Supplier.customers' or 'Supplier.place_ptr'.
                

اضافه کردن related_name به فیلد Customers به شکل زیر، error را برطرف میکند:


                  models.ManyToManyField(Place, related_name='provider').
                


مشخص کردن فیلد parent link



همانطور که گفته شد، Django به شکل اتوماتیک یک OneOneFiled ایجاد میکند و child class را به یک مدل parent غیر انتزاعی، متصل میکند. اگر بخواهید نام صفتی که به parent متصل میشود را کنترل کنید، میتوانید OneToOneFiled خود را ایجاد کرده و مقدار parent_link= True قرار دهید تا مشخص کنید که فیلد شما به parent class مرتبط شده است.



مدل های proxy در Django



زمانی که از وراثت چند جدولی استفاده میکنید، برای هر subclass مدل، یک جدول دیتابیس ایجاد میشود. از آنجایی که هر subclass به مکانی برای ذخیره فیلد های اضافی داده که در base class موجود نیست، دارد این عملکرد معمولامورد دلخواه ماست. اما گاهی ممکن است بخواهید فقط عملکرد پایتون را در یک مدل تغییر دهید. مثلا manager پیش فرض را تغییر دهید و یا یک متد جدید اضافه کنید.


برای کاربه وسیله ی وراثت مدل های پروکسی انجام میشود: ایجاد یک پروکسی برای مدل orginal. شما میتوانید instance هایی از delete و update برای مدل پروکسی ایجاد کنید و تمام داده ها را، مانند زمانی که از مدل orginal استفاده میکنید، ذخیره کنید. تفاوت اصلی این است که میتوانید اجزایی مانند ordering پیش فرض در مدل و یا manager پیش فرض در پروکسی را، بدون تغییر orginal، تغییر دهید.


مدل های پروکسی مانند مدل های معمولی تعریف میشوند و با تعیین مقدارصفت proxy در meta class، به True به Django اعلام میکنید که این این مدل، یک مدل پروکسی است.


برای مثال، فرض کنید که میخواهید یک متد به مدل Person اضافه کنید. میتوانید این کار را به شکل زیر انجام دهید:



                 from django.db import models

                 class Person(models.Model):
                     first_name = models.CharField(max_length=30)
                     last_name = models.CharField(max_length=30)

                 class MyPerson(Person):
                     class Meta:
                         proxy = True

                     def do_something(self):
                         # ...
                         pass
                

کلاس MyPerson، بر جدول دیتابیسی یکسانی با parent خود، کلاس Person، عمل میکند. به طور خاص، هر instance جدید از Person نیز از طریق MyPerson قابل دسترسی است، و برعکس:


                 >>> p = Person.objects.create(first_name="foobar")
                 >>> MyPerson.objects.get(first_name="foobar")
                 
                

شما همچنین میتوانید از یک مدل پروکسی برای تعریف ordering پیش فرض متفاوت در یک مدل استفاده کنید. اگر بخواهید مدل Person را مرتب کنید، میتوانید با استفاده از پروکسی، صفت last_name را مرتب کنید:


                 class OrderedPerson(Person):
                     class Meta:
                         ordering = ["last_name"]
                         proxy = True
                

حالا کوئری های نرمال Person، نامرتب شده و کوئری های OrderedPerson بنابر last_name مرتب میشوند.


وراثت صفات Meta در مدل های پروکسی، مانند مدل های معمولی است.


QuerySets مدلی را که درخواست داده شده برمیگردانند


Django هرگز مقداری مانند شی MyPerson، زمانی که برای اشیا Person کوئری بزنید، را بر نمیگرداند. یک queryset برای یک شی Person همان نوع شی را برمیگرداند. هدف اصلی اشیا پروکسی این است که کدی که بر مبنای Person Original است از آنها استفاده کند و کد شما میتواند از extension هایی که شما اضافه کردید( که کد دیگری بر مبنای آن نیست) استفاده کند. اینکه مدل Person (یا هر مدل دیگری را) همه جا با چیزی که خودتان ایجاد کردید عوض کنید، راه مناسبی نیست.



محدودیت های کلاس پایه



یک مدل پروکسی باید دقیقا زیرشاخه ی یک model class غیر انتزاعی قرار بگیرد( به ارث ببرد). وراثت از چند مدل غیر انتزاعی غیر ممکن است زیرا که مدل پروکسی هیچ ارتباطی بین ردیف ها در جداول مختلف دیتابیس ایجاد نمیکند. یک مدل پروکسی میتواند از هر تعداد دلخواهی از کلاس های انتزاعی وراثت داشته باشد اما فقط در صورتی که آنها هیچ فیلدی در مدل تعریف نکنند. یک مدل پروکسی همچنین میتواند از چندین مدل پروکسی، که parent class غیر انتزاعی مشترکی دارند، وراثت داشته باشد.



manager های مدل پروکسی



اگر هیچ model manager ای در یک مدل پروکسی مشخص نشده باشد، manager را از model parents خود به ارث میبرد. اگر یک manager بر proxy model تعریف کنید، تبدیل به manager پیش فرض میشود. اما هر manager که در کلاس های parent تعریف شده باشد، همچنان در دسترس خواهد بود.


در ادامه مثال بالا، شما میتوانید manager پیش فرض را با ایجاد یک کوئری برای مدل Person تغییر دهید:


                 from django.db import models

                 class NewManager(models.Manager):
                     # ...
                     pass

                 class MyPerson(Person):
                     objects = NewManager()

                 class Meta:
                     proxy = True
                

اگر یک manager جدید به proxy اضافه کنید، به طوریکه جایگزین پیش فرض موجود نشود، میتوانید از تکنیک های موجود در بخش custom manager استفاده کنید: یک کلاس پایه بسازید که شامل manager جدید باشد و آن را primary base class به ارث ببرد:


                 # Create an abstract class for the new manager.
                 class ExtraManagers(models.Model):
                     secondary = NewManager()

                     class Meta:
                         abstract = True

                class MyPerson(Person, ExtraManagers):
                    class Meta:
                        proxy = True
                

شما اغلب نیازی به انجام این کار ندارید، اما اگر داشته باشید، کاملا امکان پذیر است.



تفاوت بین وراثت پروکسی و مدیریت نشده ( unmanaged) در مدل ها



وراثت در مدل های پروکسی تا حدی شبیه به ایجاد یک مدل مدیریت نشده است که با ایجاد صفت managed در meta class مدل انجام میشود.


شما میتوانید با تنظیم صحیح Meta.db_table، یک مدل مدیریت نشده ایجاد کنید که بر یک مدل موجود سایه افکنده و متد های پایتون را به آن اضافه میکند. اما این روش بسیار شکننده و تکراری است زیرا که در صورت تغییر باید هر دو کپی را همگام (synchronized) تغییر دهید.


از طرفی دیگر مدل های پروکسی دقیقا شبیه مدلی که به آن پروکسی میزنند رفتار میکنند و از آنجایی که فیلد ها و manager های خود را از مدل parent خود به ارث میبرند، همواره با آن همگام هستند.


قوانین کلی به شکل زیر هستند:


  • اگر شما یک مدل موجود و یا یک جدول دیتا بیس را، که تمام ستونهای آن را لازم ندارید، منعکس میکنید از Meta.managed=False استفاده کنید. این گزینه معمولا برای مدل کردن view های دیتا بیس و جداول که تحت کنترل Django نیستند، استفاده میشود.

  • اگر میخواهید تنها رفتار پایتون را در یک مدل تغییر دهید و تمام فیلد ها را به همان شکلی که در original میباشد، نگهدارید، از Meta.proxy=True استفاده کنید. این کار باعث میشود مدل پروکسی در زمان ذخیره اطلاعات دقیقا یک کپی از ساختار ذخیره شده مدل orginal باشد.



وراثت چندتایی در Django



مانند ایجاد subclass در پایتون، برای یک مدل Django نیز ممکن است که از چند parent model، وراثت بپذیرد. دقت کنید که قوانین نام گذاری پایتون همچنان اعمال میشود. نام خاصی( مانند Meta) که در اولین کلاس پایه ظاهر شود، مورد استفاده قرار میگیرد: برای مثال، اگر چندین parent دارای کلاس Meta باشند، تنها اولین آنها مورد استفاده قرار میگیرد و بقیه نادیده گرفته میشوند.


به طور کلی شما نیازی ندارید از چند parent وراثت بپذیرید. استفاده اصلی این بحث برای کلاس های “mix_in” میباشد. که به معنای اضافه کردن یک فیلد اضافی مشخص و یا یک متد به تمام کلاس هایی است که از mix_in، ارث میپذیرند. سعی کنید سلسله مراتب وراثت خود را تا حد ممکن ساده نگهدارید تا برای یافتن بخشی از اطلاعات با مشکل روبرو نشوید.


توجه کنید که وراثت از چند مدل که دارای id مشترکی به عنوان فیلد کلیداصلی هستند، با error مواجه خواهد شد. برای استفاده صحیح از چند وراثت میتوانید از AutoFiled در مدل پایه استفاده کنید:


                class Article(models.Model):
                    article_id = models.AutoField(primary_key=True)
                    ...

                class Book(models.Model):
                    book_id = models.AutoField(primary_key=True)
                    ...

                class BookReview(Book, Article):
                    pass
                

و یا از یک parent مشترک برای نگهداری AutoFiled استفاده کنید. برای این کار نیاز به یک OneToOneFiled از هر مدل parent به parent مشترک دارید تا از درگیری بین فیلد هایی که اتوماتیک ایجاد میشوند و توسط یک child به ارث برده میشوند، جلوگیری شود:


                class Piece(models.Model):
                    pass

                class Article(Piece):
                    article_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
                    ...

                class Book(Piece):
                    book_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
                    ...

                class BookReview(Book, Article):
                    pass
                

نام فیلد “hiding” مجاز نیست


دروراثت کلاس های نرمال پایتون، برای یک child class مجاز است که هر صفت از parent class را override کند. در Django این کارمعمولا برای فیلد های مدل مجاز نیست. اگر یک مدل کلاس پایه غیر انتزاعی، دارای یک فیلد به نام author باشد، شما نمیتوانید یک فیلد مدل دیگر و یا یک صفت دیگر به نام author، در هر کلاسی که از کلاس پایه وراثت دارد، ایجاد کنید.


این محدودیت ها بر فیلد های مدلی که از یک مدل انتزاعی به ارث رسیده اند، اعمال نمیشود. این فیلدها میتوانند با یک فیلد و یا یک مقدار دیگر override شوند و یا با تنظیم filed_name =None، حذف شوند.


هشدار:

manager های مدل از کلاس های انتزاعی پایه به ارث میرسند. override کردن یک فیلد به ارث رسیده، که توسط یک Manager به ارث رسیده ارجاع داده میشود، میتواند باعث ایجاد bug در سیستم شود. برای اطلاعات بیشتر به custom managers and model inheritance مراجعه کنید.



توجه:

برخی از فیلد ها، صفات اضافی بر مدل تعریف میکنند، مثلا ForeignKey یک صفت اضافه با _id ضمیمه شده به نام فیلد تعریف میکند، همچنین related_name و related_query_name در مدل خارجی.


این صفات اضافه، نمیتوانند override شوند، مگر زمانی که فیلدی که آنها را تعریف کرده است ، حذف شود و یا تغییر کند و دیگر این صفات اضافه را تعریف نکند.



override کردن فیکد ها در مدل parent باعث ایجاد مشکلاتی در مقدار دهی اولیه به instance های جدید ( مشخص کردن اینکه کدام فیلد در Model._ _init_ _ مقدار دهی شود) و ترتیب سلسله مراتبی آنها میشود. این امکانات در وراثت نرمال کلاس های پایتون وجود ندارد، در نتیجه تفاوت بین وراثت مدل Django و وراثت کلاس پایتون، اتفاقی نیست.


این محدودیت های تنها شامل صفاتی میشوند که instance هایی از فیلد هستند. صفات معمول پایتون میتوانند در صورت تمایل ، override شوند. هچنین درباره نام صفت ها، تنها محدودیت های پایتون موجود است و اگر شما به شکل دستی نام ستون های دیتابیس را مشخص میکنید، میتوانید از نام مشابه برای ستون مدل های child و parents در وراثت چند جدولی استفاده کنید( این ستون ها در دو جدول متفاوت هستند.)


Django در صورت ovrride فیلد مدل در هریک از مدل های parents، ایجاد FiledError میکند.



مرتب کردن مدل ها در یک پکیج



دستور manage.py startapp یک ساختار اپلیکیشن ایجاد میکند که شامل فایل models.py است. اگر شما تعداد زیادی مدل داشته باشید، مترب کردن آنها در فایل های متفاوت بسیار مفید خواهد بود.


برای این کار، یک models package ایجاد کنید. تمام models.py ها را حذف کنید و یک دایرکتوری myapp/models/ با یک فایل _ _ init_ _.py و فایل هایی که برای ذخیره مدل خود استفاده میکنید ، بسازید. باید مدل های خؤد را در فایل


_ _init_ _.py ، import کنید.


برای مثال، اگر در دایرکتوری models، فایل organic.py و synthetic.py را دارید:


              myapp/models/__init__.py

              from .organic import Person
              from .synthetic import Robot
                

import کردن هر مدل به جای استفاده از from .models import*، باعث میشود namespace به هم ریخته نشود، کد خوانایی بیشتری داشته باشد و ابزار های آنالیز کد استفاده مفیدی داشته باشند.

  • 163
  •    138
  • تاریخ ارسال :   1399/09/14

دانلود PDF دانشجویان گرامی اگر این مطلب برای شما مفید بود لطفا ما را در GooglePlus محبوب کنید
رمز عبور: tahlildadeh.com یا www.tahlildadeh.com
ارسال دیدگاه نظرات کاربران
شماره موبایل دیدگاه
عنوان پست الکترونیک

ارسال

آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

تمامی حقوق این سایت متعلق به آموزشگاه تحلیل داده می باشد .