کدستانِ من



1) getElementsByTagName

اولین تابع برای دسترسی به عنصرها، استفاده از اسم تگ هاست. این تابع اسم تگ را به عنوان ورودی می گیرد. برای مثلا برای انتخاب تگ های p از کد:

document.getElementsByTagName("p")

استفاده می کنیم. توجه کنید که این تابع آرایه ای از تگ های مورد نظر را برمی گرداند.

  مثال:  


    <p id="text">Click the button to change me.</p>
    <button onclick="changeText()">click me</button>
    <script>
        function changeText() {
	    document.getElementsByTagName("p")[0].innerHTML = "I am changed";
	}
    </script>
    
    


2) getElementById

اگر بخواهیم عناصر را با استفاده از اسم آی دی آن ها انتخاب کنیم از این تابع استفاده می کنیم. این تابع (اسم) آی دی را به عنوان ورودی می گیرد و یک عنصر را برمی گرداند. 

  مثال:  


    <p id="text">Please READ ME.</p>
    <button onclick="read()">click me</button>
    <script>
        function read() {
            document.getElementById("text").style.fontSize = "40px";
        }
    </script>


3) getElementsByClassName

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

  مثال:  


  <p>This is an <span class="important">important</span> announcement.</p>
  <p>Please <span class="important">pay attention</span>.</p>
  <p>Please read this <span class="important">carefully</span>.</p>
  <button onclick="attention()">pay attention</button>
  <script>
    function attention() {
      let x = document.getElementsByClassName("important");
      for(let i = 0; i < x.length; i++) {
        x[i].style.color = "red";
      }
    }
  </script>



4)  querySelectorAll

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

  مثال:  


  <div class="row">
      <div class="col-1">col-1</div>
      <div class="col-2">col-2</div>
      <div class="col-1">col-1</div>
      <div class="col-1">col-1</div>
      <div class="col-3">col-3</div>
    </div>
    <button onclick="oneline()">Line the DIVs</button>
  <script>
    function oneline() {
      var elms = document.querySelectorAll('[class^="col-"]');
      for(let i = 0; i < elms.length; i++) {
        elms[i].style.float = "left";
        }
      }
  </script>






حروف

npm نمایش دهنده ی node package manager هستند. اگر شما در حال کار روی یک پروژه ی جاوااسکریپت باشید - فرقی نمی کند این پروژه یک برنامه ی تحت وب مانند آنگولار یا یک برنامه ی سمت سرور مثل نود باشد می توانید از npm استفاده کنید تا پکیج های کدِ افراد دیگر را در برنامه ی خود نصب کنید. منظور از پکیج هر قطعه کدی است که یک شخص تصمیم گرفته است آنرا از طریق npm منتشر کند.

npm در واقع یک ابزار است که باید آنرا روی سیستم کامپیوتر خود نصب کنید و بعد از نصب می توانید از آن برای نصب پکیج های مورد نظر در پروژه ی خود استفاده کنید. npm بخشی از

برنامه ی نود جی اس است بنابراین با

نصب آخرین نسخه ی نود، npm هم بصورت اتوماتیک در سیستم شما نصب می شود و بعد از نصب می توانید از دستورات آن در خط فرمان استفاده کنید. برای نصب، حذف و به روز رسانی پکیج های npm باید از خط فرمان سیستم خود استفاده کنید.

هزاران پکیج npm وجود دارد که با رفتن به سایت

npmjs به آن ها دسترسی دارید. با اینحال توصیه می شود برای انتخاب و نصب پکیج صحیح ابتدا در گوگل جستجو کنید.

 

برای به کارگیری npm در پروژه، پروژه باید شامل فایلی به اسم package.json باشد. این فایل شامل اسم پکیج های مورد استفاده ی پروژه می باشد و در آن نسخه ی پکیج هم مشخص شده است.

اگر پروژه ی شما فایل package.json را ندارد باید ابتدا آن را ایجاد کنید. برای ایجاد این فایل باید در برنامه ی خط فرمان سیستم خود به فولدر پروژه بروید و سپس از دستور

npm init

استفاده کنید. بعد از انجام تنظیمات لازم، فایل package.json برای پروژه ی شما ایجاد می شود. اگر پروژه ی شما فایل package.json را دارد نیازی به اجرای این مرحله نیست.

 

بنابر شرایط متفاوت ممکن است لازم باشد که پکیج های موجود در فایل package.json را دوباره نصب کنید. برای مثال اگر بخواهید پروژه ی خود را در کامپیوتر جدید اجرا کنید ابتدا باید پکیج های مورد نیاز آن را نصب کنید. برای این کار از دستور

npm install

استفاده می شود. بعد از اجرای این دستور می بینید که فولدر جدیدی به اسم node_modules کنار فایل package.json ایجاد شده است و کد پکیج های موجود در این فایل در آن وارد شده است.

 

برای این که پکیج جدیدی را به پروژه ی خود وارد کنید دستور npm install با اسم پکیج همراه می شود. برای اینکه اسم پکیج در فایل package.json ذخیره شود در انتهای این دستور –save قرار می دهیم. برای مثال برای نصب پکیج Express در پروژه ی نود جی اس از دستور

npm install express –save

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

 

منبع نوشته:

سایت مدیوم


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


countries = [
    'China', 'United States', 'Brazil', 
    'Mexico', 'Japan', 'Vietnam', 
    'Egypt', 'France', 'Poland', 
    'Peru', 'Angola', 'Cuba'
]
populations = [
    1437667374, 330397596, 212101777, 
    128515225, 126593764, 97073748, 
    101738000, 65224185, 37861667,
    32841517, 32544138, 11328301
]

اولین راهی که به ذهن می رسد این است که از یک ایندکس برای دسترسی به عناصر لیست بهره ببریم. این عمل با کمک حلقه های while و for امکانپذیر است.


# (1)
i = 0
while i < len(countries):
    print(countries[i])
    i += 1

# (2)
for j in range(len(populations)):
    print(populations[j])

هرچند این عملیات از نظر کارکرد و نتیجه درست هستند اما استفاده از آن ها منطقی به نظر نمی رسد. در این روشِ استفاده از حلقه ها از ویژگی های خاص پایتون استفاده نشده است. در پایتون دیتاتایپ هایی مثل لیست و دیکشنری به صورت پیش فرض iterable هستند که به این معنی است که می توان با کمک حلقه ی for مستقیم به عناصر دسترسی داشت و آن ها را یکی یکی برشمرد. این حلقه دقیقا نتیجه ای برابر کد (۱) دارد ولی استفاده از آن بهتر است.


# (3)
for country in countries:
    # do something with country
    print(country)

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


# (4)
i = 1
for country in countries:
    print(i, country)
    i += 1

به جای کد (۴) و تعریف ایندکس جداگانه راه حل زیر، روش بسیار بهتری است.

# (5)
for index, country in enumerate(countries):
    print(index+1, country)

اگر بخواهیم عناصر دو لیست را تکرار کنیم هم راه حل زیر، روش خوبی نیست.


# (6)
i = 0
for i in range(len(countries)):
    country = countries[i]
    population = populations[i]
    print(country, ':', population)

به جای این روش بهتر است از راه زیر استفاده کرد.


# (7)
for country, population in zip(countries, populations):
    print(country, ':', population)

 

در این پست دیدیم که چطور با کمک ویژگی های پایتون می توان عناصر لیست را تکرار کرد. از این ویژگی ها می توان برای دسترسی به همه ی اشیایی که iterable هستند استفاده کرد.

 


همانطور که می دانید Django ORM ابزاری برای ایجاد، حذف، بازیابی و به روز رسانی داده ها در دیتابیس را در اختیار ما قرار داده است. گاهی در ارتباط با دیتابیس به عملیات پیچیده تری نیاز داریم. یکی از ابزارهای در دسترس aggregate و annotate هستند که برای متراکم کردن یا خلاصه سازی اطلاعات به کار می روند. اگر درخواست های ما به دیتابیس شامل عملیاتی مثل شمردن، میانگین گیری، جمع کردن، یافتن ماکزیمم و مینیمم باشد می توان از aggregate و annotate استفاده کرد.

 

در مثال های این بخش از مدل های زیر استفاده شده است:


class Brand(models.Model):
    name = models.CharField(max_length=50)

class Product(models.Model):
    name = models.CharField(max_length=100)
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
    price = models.PositiveIntegerField()
    amount = models.PositiveSmallIntegerField()

اگر بخواهیم آمارگیری را از کل یک QuerySet انجام بدهیم از aggregate استفاده می کنیم. برای مثال اگر بخواهیم تعداد کل محصولات را پیدا کنیم یک روش موجود، استفاده از aggregate است.


from django.db.models import Sum

Product.objects.aggregate(Sum('amount'))
>>>{'amount__sum': 114}

همانطور که می بینید aggregate یک دیکشنری پایتون برمی گرداند. در نتیجه نمی توان روی نتیجه ی آن از متدهای کوئری ست مثل filter، values و . استفاده کرد.

حال می خواهیم تعداد محصولات را در هر برند پیدا کنیم. در این حالت دیگر نمی خواهیم نتیجه را از کل داده ها پیدا کنیم بلکه هدف پیدا کردن نتیجه در هر گروه برندها است. در این صورت دیگر نمی توان از aggregate استفاده کرد و به جای آن باید از annotate استفاده کرد.
متد
annotate در واقع GROUP BY دیتابیس های SQL را پیاده سازی می کند. این متد برخلاف aggregate لیستی از کوئری ست ها را بر می گرداند در نتیجه می توان روی آن عملیاتی مثل filter، values، order_by و . را انجام داد.
پیدا کردن تعداد محصولات هر برند با
SQL به شکل زیر انجام می شود:

SELECT Brand.name, SUM(Product.amount) AS Brand_sum
FROM Brand LEFT OUTER JOIN Product ON Brand.id=Product.brand
GROUP BY Brand.name;

همین دستور SQL را می توان با annotate به شکل زیر پیاده سازی کرد:
 


from django.db.models import Sum

brands = Brand.objects.annotate(brand_sum=Sum('product__amount'))
for brand in brands:
    print(brand.name, ' : ', brand.brand_sum)

که کوئری متناظر با آن در جنگو ORM به صورت زیر است:

SELECT "test_group_brand"."id", "test_group_brand"."name", SUM("test_group_product"."amount") AS "brand_sum"
FROM "test_group_brand" LEFT OUTER JOIN "test_group_product" ON ("test_group_brand"."id" = "test_group_product"."brand_id")
GROUP BY "test_group_brand"."id", "test_group_brand"."name"

 

البته مسئله ی بالا را می توان به شکل زیر هم نوشت:


from django.db.models import Sum

brands = Product.objects.values('brand__name').annotate(brand_sum=Sum('amount'))


که کوئری متناظر با آن به این صورت است:
 

SELECT "test_group_brand"."name", SUM("test_group_product"."amount") AS "brand_sum"
FROM "test_group_product" INNER JOIN "test_group_brand" ON ("test_group_product"."brand_id" = "test_group_brand"."id")
GROUP BY "test_group_brand"."name"

همانطور که گفته شد می توان متدهای کوئری ست را روی نتیجه ی annotate اعمال کرد. برای مثال اگر بخواهیم نام برندهایی که بیش از ۷۰۰ عدد موجودی دارند را مشخص کنیم از قطعه کد زیر استفاده می کنیم:

 


from django.db.models import Sum

brands = Brand.objects.annotate(brand_sum=Sum('product__amount')).filter(brand_sum__gt=700).values('name','brand_sum')

که کوئری آن برابر است با:

SELECT "test_group_brand"."name", SUM("test_group_product"."amount") AS "brand_sum"
FROM "test_group_brand" LEFT OUTER JOIN "test_group_product" ON ("test_group_brand"."id" = "test_group_product"."brand_id")
GROUP BY "test_group_brand"."id", "test_group_brand"."name"
HAVING SUM("test_group_product"."amount") > 400


مدل ها در جنگو با فیلدهایی مانند CharField، IntegerField، BooleanField و . تعریف می شوند. این فیلدها برای دیتابیس sqlite3 که بصورت پیش فرض در جنگو وجود دارد مورد استفاده قرار می گیرند.

اگر ما دیتابیس را به جای

sqlite3 به

Postgres تغییر دهیم این دیتابیس تعدادی فیلدهای مختص خود را به مدل های ما اضافه می کند. این فیلدها شامل JSONField، HStoreField، CITextField، ArrayField و فیلدهای Range هستند. در این پست به معرفی ‌

ArrayField می پردازیم.

این فیلد همانطور که از نامش پیداست به ما این امکان را می دهد که آرایه ای از داده ها را به دیتابیس اضافه کنیم. داده های آرایه باید از یک نوع باشند.

class ArrayField(base_field, size=None, **options)

base_field همان نوع داده های ورودی است که تعریف آن اجباری است و نوع آن باید از فیلدهای مدل مشخص شود برای نمونه نوع آن می تواند CharField یا IntegerField تعریف شود. نوع آن می تواند از نوع آرایه هم باشد. یعنی آرایه ای از آرایه ها داشته باشیم. استفاده از همه ی مدل ها به جز

فیلدهای ارتباطی یعنی OneToOneField، ForeignKey و ManyToManyField ممکن است.

آرگومان ورودی Size حداکثر سایز آرایه را مشخص می کند و تعریف آن اختیاری است. البته در حال حاضر دیتابیس Postgres اندازه ی آرایه را به این سایر محدود نمی کند و آن را نادیده می گیرد.


from django.contrib.postgres.fields import ArrayField
from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=200)
    colors = ArrayField(models.CharField(max_length=20, blank=True))

جستجو در ArrayField

علاوه بر راه های جستجویی که برای همه ی مدل ها وجود دارد ArrayField تعدادی فیلد جستجوی مختص هم دارد. در این بخش از مدل تعریف شده ی بالا استفاده می شود که سه نمونه شیء زیر از آن در دیتابیس ساخته شده اند.

>>> Product.objects.create(name='Mobile phone Samsung', colors=['red','white','black'])
>>> Product.objects.create(name='Laptop Toshiba 2020', colors=['black'])
>>> Product.objects.create(name='IPad', colors=['white','yellow'])

۱) contains

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

>>> Product.objects.filter(colors__contains=['black'])

که نتیجه ی زیر را به ما می دهد:


<QuerySet [<Product: Mobile phone Samsung>, <Product: Laptop Toshiba 2020>]>

۲) contained_by

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

۳) overlap

این جستجو برای این به کار می رود که هرگونه اشتراکی بین داده ها و مقدار ورودی را پیدا کند.

۴) len

طول آرایه را برمیگرداند.

>>> Product.objects.filter(colors__len=1)

که نتیجه ی زیر را به ما می دهد:

 

<QuerySet [<Product: Laptop Toshiba 2020>]>

۵) index transform

جستجوی ایندکسی آرایه را برمیگرداند.
 

>>> Product.objects.filter(colors__1='white')
>>> Product.objects.filter(colors__100='red')

که به ترتیب چنین نتیجه ای دارند:

 

<QuerySet [<Product: Mobile phone Samsung>]>

<QuerySet []>

۶) slice transform

جستجوی بخشی از آرایه را برمیگرداند.


در بعضی زبان های برنامه نویسی مثل جاوا و ++C دسترسی به منابع با کلمات کلیدی private، public و protected کنترل می شوند. یکی از اهداف این کار محصورسازی داده ها (data encapsulation) در زبان های شی گرا است.
اعضای
public کلاس اعضایی هستند که هرچند در کلاس تعریف می شوند ولی از بیرونٍ کلاس قابل دسترسی هستند.
اعضای
private اعضایی هستند که محدود به کلاسی هستند که در آن تعریف می شوند و امکان دسترسی به آن ها از طریق بیرون کلاس وجود ندارد.
اعضای
protected نیز از خارج از کلاس قابل دسترسی نیستند ولی زیرکلاس ها اجازه ی دسترسی به آن ها را دارند.

 

در این میان زبان پایتون ساز و کار موثری برای پیاده سازی اعضای private، public و protected ندارد. پایتون با کمک روش پیشوندگذاری اعضا مکانیزم عدم دسترسی به اعضا را شبیه سازی می کند ولی در واقعیت این کار، عمل محدودکردن دسترسی را انجام نمی دهد. پایتون درعمل دسترسی به داده های private و protected را محدود نمی کند و فقط برنامه نویسان را به این کار متعهد کرده است. در واقع خود برنامه نویسان با دیدن پیشوندهای مشخص کننده ی اعضای private و protected باید از دسترسی و تغییر آن ها پرهیز کنند.

 

اعضا در پایتون به صورت پیش فرض public هستند. اعضای public از خارج از کلاس قابل دسترسی هستند.


class Foo:
    def __init__(self, x):
        self.x = x

در این مثال x یک عضو public است که از خارج از کلاس قابل دسترسی و تغییر است.


>>> foo = Foo(10)
>>> foo.x
10
>>> foo.x = 222
>>> foo.x
222

قرارداد پایتون برای تعریف اعضای protected اضافه کردن _ (زیرین خط یا underscore) است. این تعریف دسترسی به عضو را به جز برای خود کلاس و زیرکلاس های آن ممنوع می کند.


class MathTest:
    def __init__(self, a, b):
        self.first_number = a
        self.second_number = b

    def _add(self):
        return self.first_number + self.second_number

    def print_sum(self):
        sum = self._add()
        print('Sum of {} and {} is {}'.format(self.first_number, self.second_number, sum))

البته در واقعیت مثال بالا دسترسی به متد add که protected است را منع نمی کند و هنوز هم امکان انجام عملیات زیر خارج از کلاس وجود دارد!


>>> test = MathTest(10,20)
>>> test.print_sum()
Sum of 10 and 20 is 30
>>> test2 = MathTest(111,222)
>>> print(test2._add())
333

با اینحال همانطور که گفته شد پایتون برنامه نویسان مسئول را از دسترسی و تغییر اعضای protected منع کرده است و آن ها را متعهد به این کار کرده است.

 

اعضای private در پایتون با __ (دو زیرین خط یا دو underscore) تعریف می شوند. با اینکار دسترسی به آن ها خارج از کلاس ممنوع می باشد.


class Employee:
    def __init__(self, name, salary):
        self.__name = name
        self.__salary = salary

تفاوتی که این حالت با مثال پیش دارد این است که دسترسی مستقیم به متغیرهای private وجود ندارد و دسترسی زیر موجب ایجاد خطای AttributeError می شود.


>>> employee = Employee('John Doe', 20000)
>>> employee.__salary 
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: Employee instance has no attribute '__salary'

با اینحال اعضای private باز هم خارج از کلاس قابل دسترسی هستند. وجود __ این اعضا را به به متغیرهای object__variablename_ تبدیل می کند. بنابراین اعضای private را می شود به صورت زیر دید و تغییر داد هرچند باید از این کار پرهیز کرد.


>>> employee = Employee('Anna Bole', 30000)
>>> employee._Employee__salary
30000
>>> employee._Employee__salary = 44400
>>> employee._Employee__salary
44400

همانطور که گفته شد در برخی زبان های برنامه نویسی امکان تعریف اعضای private، public و protected با کلمات کلیدی وجود دارد. این کلمات کلیدی عملا دسترسی به اعضا را محدود یا از آن جلوگیری می کنند. در پایتون نیز به صورت قراردادی برای تعریف اعضای protected از _ و اعضای private از __ استفاده می شود. این تعریف های قراردادی در عمل مانع از دسترسی به اعضا نمی شوند ولی پایتون برنامه نویسان را متعهد و مسئول این کار می داند و آن ها را از دسترسی و تغییر اعضای private و protected خارج از کلاس منع می کند.

 


مدل های جنگو مانند هر کلاس دیگری در پایتون می توانند از یکدیگر ارث بری کنند. برای مدل های جنگو سه نوع وراثت وجود دارد. یک نوع وراثت به صورت

ابسترکت (abstract) است و یک نوع به صورت غیر ابسترکت که به صورت

وراثت چند جدولی (multi-table inheritance) است. نوع سوم وراثت نیز حالتی است که هدف تغییر فیلدهای مدل نیست بلکه می خواهیم رفتار یک مدل را تغییر دهیم و به آن مدل

پراکسی (proxy) گفته می شود. در این پست در مورد وراثت غیرابسترکت صحبت می کنیم.


اگر مدل های جنگو به صورت معمولی از یکدیگر ارث بری کنند وراثت چندجدولی خواهیم داشت. علت نامگذاری هم این است که به ازای هر کلاس یک جدول جدا در دیتابیس تشکیل می شود.
در این نوع ارث بری ویژگی های مشترک در یک کلاس یا جدول
parent گذاشته می شوند و بعد هر کلاس یا جدول child فیلدهای مختص خودش را خواهد داشت که با یک

کلید خارجی به کلاس یا جدول parent اشاره می کند. البته توجه کنید که در ORM جنگو این کلید خارجی به صورت

فیلد OneToOneField پیاده سازی شده است


from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=225)
    price = models.PositiveIntegerField()

class DigitalProduct(Product):
    screen_size = models.PositiveSmallIntegerField()
    os = models.CharField(max_length=100, null=True)

class ElectronicProduct(Product):
    energy = models.PositiveSmallIntegerField()

class Mobile(DigitalProduct):
    camera_resolution = models.PositiveIntegerField()
    sim_cards = models.PositiveIntegerField()

class Laptop(DigitalProduct):
    cpu = models.CharField(max_length=100)
    ram_type = models.CharField(max_length=100)

همانطور که گفته شد در مثال بالا به ازای هر کلاس یک جدول ساخته می شود. یعنی در دیتابیس اکنون جداول test_product و test_digitialproduct و test_electronicproduct و test_mobile و test_laptop وجود دارند (اسم اپ test است) که هر جدول در صورت وجود با کلید خارجی به parent خود اشاره می کند. به دلیل این نوع ذخیره سازی، امکان جستجو در کلیه ی نمونه های Product وجود دارد بدون در نظر گرفتن اینکه این نمونه ها DigitalProduct باشند یا ElectronicProduct یا نمونه های فرزند دیگر. به این ترتیب سه کوئری


>>> Product.objects.all()
>>> ElectronicProduct.objects.all()
>>> Laptop.objects.all()

به ترتیب

  • همه ی اشیای Product (شامل نمونه های Mobile, DigitalProduct, ElectronicProduct, Product و Laptop)
  • اشیای ElectronicProduct
  • اشیای Laptop

را جستجو می کنند.

 

با این تفاسیر وراثت چند جدولی چنین ویژگی هایی دارد:

  • جستجو در همه ی اشیاء یک نوع
  • ارتباط همه ی اشیای یک نوع (با کلید خارجی)

این نوع وراثت همچنین این معایب را دارد:

  • چون به ازای هر کوئری، عملیات افزودن، حذف یا به روزرسانی باید در همه ی جدول های زنجیره ی وراثت انجام شود کوئری های بیش تری نیاز است.
  • در عمل به ازای کوئری های select میان جدول ها پیوست (join) صورت می گیرد! بنابراین به ازای هر کوئری باید میان جداول زنجیره ی وراثت پیوست های زیادی انجام شود. هرچه این زنجیره ی وراثت طولانی تر باشد تعداد پیوست ها بیش تر است.

 

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


آخرین ارسال ها

آخرین وبلاگ ها

آخرین جستجو ها