<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های MrYazdan</title><link>https://virgool.ir/feed/@mryazdan</link><description></description><language>fa</language><pubDate>2026-11-10 23:10:51</pubDate><image><url>https://files.virgool.ir/upload/users/2710477/avatar/RCX5NN.jpg</url><title>MrYazdan</title><link>https://virgool.ir/@mryazdan</link></image><item><title>ارث بری مدل ها در جنگو - قسمت دوم ?</title><link>https://virgool.ir/@mryazdan/ارث-بری-مدل-ها-در-جنگو-قسمت-دوم-n4xaxptuytvm</link><description>Djnago Model Inheritanceتمام سند های متنشر شده در ویرگول ، در مخزن عمومی خود در گیتهاب وجود دارند (اول اونجا منتشر میشه ? ) : https://github.com/code-barg/daily-django-tips-fa جلسه قبل تر : ارث بری مدل ها در جنگو - قسمت اولبه نام خدا ، سلام سلام ?️ اومدیم با قسمت دوم ارث بری در مدل های فریمورک محبوب جنگو ، در قسمت قبل از مدل های انتزاعی و ارث بری ازشون گفتیم حالا بریم سراغ نوع دوم ارث بری ها که به پراکسی (proxy) معروفه بپردازیم ?مانند قبل ، بریم تعریف این نوع از مدل رو از خود جنگو ببینیم ❓Sometimes, however, you only want to change the Python behavior of a model – perhaps to change the default manager, or add a new method.This is what proxy model inheritance is for: creating a proxy for the original model. You can create, delete and update instances of the proxy model and all the data will be saved as if you were using the original (non-proxied) model. The difference is that you can change things like the default model ordering or the default manager in the proxy, without having to alter the original.همانطور که میبینید ، جنگو داره بهمون میگه: گاهی وقت ها شما میخواهید فقط رفتار پایتونی مدلتان متفاوت باشند یا به زبان آدمیزاد ، ممکنه وقت هایی بشه که برای یک جدول ما بصورت های متفاوتی قصد دریافت یا ارسال داده رو داشته باشیم ، اینجاست proxy مدل ها بکمکمون میان. ?به مثال زیر توجه کنید :from django.db import models&#xA;from django.utils import timezone&#xA;&#xA;&#xA;class Product(models.Model):&#xA;    title = models.CharField(max_length=100)&#xA;    created = models.DateTimeField(auto_now_add=True)&#xA;    &#xA;    &#xA;class OrderedProduct(Product):&#xA;    class Meta:&#xA;        proxy = True&#xA;        ordering = [&#39;created&#39;]&#xA;&#xA;    def created_delta(self):&#xA;        return timezone.now() - self.createdخوب که بهش نگاه کنیم میبینیم هیچی نیست ! ?خب ما یک مدل Product داریم که تونستیم با ارث بری ازش یک مدل رفتاری (proxy) ازش بسازیم ، این مدل جدید با نام OrderedProduct نه ماهیت دیتابیسی داره (یعنی داخل دیتابیس چنین جدولی نیست) و نه اجازه این رو داره که تغییر دیتابیسی در مدل اصلی ایجاد کنه !سوال : پس فایدش چیه ؟ (به چه دردی میخوره):❓در پاسخ به این سوال میشه اینطور گفت که این مدل ها ، زمانی که شما قصد فیلتر کردن داده های اصلی (Product) را بصورت سطحی داشته باشید یا نسبت به خاصیتی (مثلا اگر این محصول تخفیف داشت !) متد هایی نیاز داشته باشید عملا بیفایده است و میتوان راهکار های ساده تری استفاده کرد ، ولی اگر مقصودتان فقط بصورت سطحی و کلی نباشد ، قصد جداسازی به همراه استفاده از الگو های بهینه سازی کوئری ها یا مثلا استفاده از Caching بطور جزئی و حرفه ای تر را داشته باشید استفاده از مدل های پراکسی شده بسیار عالی است !نتیجه :اول) ارث بری بصورت پراکسی مدل امکان رفتار پایتونیک بهتر و مقیاس پذیر تر را به ما میدهد. ✅دوم) در این نوع ارث بری ، ما نمیتوانیم تغییری در باطن یا ساختار اصلی مدل ایجاد کنیم. ❎مثال عملی و باحال از جلسه امروز (اهل دلاش اینجاشو دوست دارن ?)فایل ‍‍models.py‍ ما اینشکلیه :from django.db import models&#xA;from django.contrib.auth.models import Group, Permission, User&#xA;&#xA;&#xA;class SecurityFilter(models.Model):&#xA;    &#34;&#34;&#34;&#xA;    Security filter for a permission and a group by filter conditions.&#xA;    The filter conditions are evaluated in the context of the user.&#xA;&#xA;    For example, if the filter conditions are &#34;user.is_staff == True&#34;,&#xA;    then the filter is applied only if the user is staff.&#xA;    &#34;&#34;&#34;&#xA;    filter_conditions = models.TextField(verbose_name=&#39;filter conditions&#39;)&#xA;    group = models.ForeignKey(to=Group, related_name=&#39;filters&#39;, on_delete=models.CASCADE)&#xA;    permission = models.ForeignKey(to=Permission, related_name=&#39;filters&#39;, on_delete=models.CASCADE)&#xA;&#xA;    def __unicode__(self):&#xA;        return &#34;%s for %s&#34; % (self.permission, self.group)&#xA;&#xA;&#xA;class SecurityUserManager(models.Manager):&#xA;    &#34;&#34;&#34;&#xA;    Manager for User model.&#xA;&#xA;    This manager provides a method to get a queryset of available security filters&#xA;    &#34;&#34;&#34;&#xA;&#xA;    @staticmethod&#xA;    def _get_filters(user, permission):&#xA;        &#34;&#34;&#34;&#xA;        Get security filters for a user and a permission.&#xA;&#xA;        :param user: auth.models.User instance&#xA;        :param permission: auth.models.Permission instance&#xA;        :return: list of SecurityFilter instances&#xA;        &#34;&#34;&#34;&#xA;        return SecurityFilter.objects.filter(permission=permission, group__in=user.groups.all())&#xA;&#xA;    @staticmethod&#xA;    def _build_query(filters):&#xA;        &#34;&#34;&#34;&#xA;        Build a query from a list of security filters.&#xA;&#xA;        :param filters: list of SecurityFilter instances&#xA;        :return: a query object&#xA;        &#34;&#34;&#34;&#xA;        if not filters:&#xA;            return None&#xA;&#xA;        query = models.Q()&#xA;        for conditions_set in (f.filter_conditions for f in filters):&#xA;            query |= models.Q(**eval(conditions_set))&#xA;&#xA;        return query&#xA;&#xA;    def available(self, user, permission):&#xA;        &#34;&#34;&#34;&#xA;        Get a queryset of available security filters for a user and a permission.&#xA;&#xA;        :param user: auth.models.User instance&#xA;        :param permission: auth.models.Permission instance&#xA;        :return: queryset of SecurityFilter instances&#xA;        &#34;&#34;&#34;&#xA;        filters = self._get_filters(user=user, permission=permission)&#xA;        query = self._build_query(filters)&#xA;&#xA;        queryset = self.get_queryset()&#xA;        if query is None:&#xA;            return queryset.none()&#xA;        else:&#xA;            return queryset.filter(query)&#xA;&#xA;&#xA;class UserProxy(User):&#xA;    &#34;&#34;&#34;&#xA;    Proxy class for User model.&#xA;    &#34;&#34;&#34;&#xA;    objects = SecurityUserManager()&#xA;&#xA;    class Meta:&#xA;        proxy = Trueچقدر ساده و پر استفاده ولی باحال ?برای تست و استفادش هم خب این هم فایل tests.py ما میتونه راهنمای کاملتون باشه :from django.test import TestCase&#xA;from django.contrib.auth.models import User, Permission, Group&#xA;from django.contrib.contenttypes.models import ContentType&#xA;&#xA;from .models import SecurityFilter, UserProxy&#xA;&#xA;&#xA;class SecurityFilterTestCase(TestCase):&#xA;    def setUp(self):&#xA;        self.joker = User.objects.create_user(username=&#39;joker&#39;)&#xA;        self.victim_1 = User.objects.create_user(username=&#39;victim_1&#39;)&#xA;        self.victim_2 = User.objects.create_user(username=&#39;victim_2&#39;)&#xA;        self.batman = User.objects.create_user(username=&#39;batman&#39;)&#xA;&#xA;        self.villains = Group.objects.create(name=&#39;villains&#39;)&#xA;        self.villains.user_set.add(self.joker)&#xA;&#xA;        self.kill_and_rob = Permission.objects.create(&#xA;            name=&#39;kill and rob&#39;,&#xA;            codename=&#39;kill_and_rob&#39;,&#xA;            content_type=ContentType.objects.get(app_label=&#39;auth&#39;, model=&#39;user&#39;)&#xA;        )&#xA;&#xA;        SecurityFilter.objects.create(&#xA;            filter_conditions=&#34;{&#39;username__startswith&#39;: &#39;victim&#39;}&#34;,&#xA;            permission=self.kill_and_rob,&#xA;            group=self.villains,&#xA;        )&#xA;&#xA;    def test_basic_filtering(self):&#xA;        condition_string = SecurityFilter.objects.get().filter_conditions&#xA;        filter_query = eval(condition_string)&#xA;&#xA;        users = User.objects.filter(**filter_query)&#xA;        victims = User.objects.filter(pk__in=[self.victim_1.pk, self.victim_2.pk])&#xA;&#xA;        self.assertEqual(set(users), set(victims))&#xA;&#xA;    def test_security_manager(self):&#xA;        users = UserProxy.objects.available(user=self.joker, permission=self.kill_and_rob)&#xA;        victims = User.objects.filter(pk__in=[self.victim_1.pk, self.victim_2.pk])&#xA;&#xA;        self.assertEqual(set(users.values_list(&#39;pk&#39;, flat=True)), set(victims.values_list(&#39;pk&#39;, flat=True)))&#xA;&#xA;    def test_security_manager_two_filters(self):&#xA;        SecurityFilter.objects.create(&#xA;            filter_conditions=&#34;{&#39;username&#39;: &#39;batman&#39;}&#34;,&#xA;            permission=self.kill_and_rob,&#xA;            group=self.villains,&#xA;        )&#xA;&#xA;        users = UserProxy.objects.available(user=self.joker, permission=self.kill_and_rob)&#xA;        victims = User.objects.filter(pk__in=[self.victim_1.pk, self.victim_2.pk, self.batman.pk])&#xA;&#xA;        self.assertEqual(set(users.values_list(&#39;pk&#39;, flat=True)), set(victims.values_list(&#39;pk&#39;, flat=True)))&#xA;&#xA;    def test_security_manager_two_groups(self):&#xA;        archvillains = Group.objects.create(name=&#39;archvillains&#39;)&#xA;        archvillains.user_set.add(self.joker)&#xA;&#xA;        SecurityFilter.objects.create(&#xA;            filter_conditions=&#34;{&#39;username&#39;: &#39;batman&#39;}&#34;,&#xA;            permission=self.kill_and_rob,&#xA;            group=archvillains,&#xA;        )&#xA;&#xA;        users = UserProxy.objects.available(user=self.joker, permission=self.kill_and_rob)&#xA;        victims = User.objects.filter(pk__in=[self.victim_1.pk, self.victim_2.pk, self.batman.pk])&#xA;&#xA;        self.assertEqual(set(users.values_list(&#39;pk&#39;, flat=True)), set(victims.values_list(&#39;pk&#39;, flat=True)))&#xA;&#xA;    def test_security_manager_two_perms(self):&#xA;        make_joke = Permission.objects.create(&#xA;            name=&#39;make joke&#39;,&#xA;            codename=&#39;make_joke&#39;,&#xA;            content_type=ContentType.objects.get(app_label=&#39;auth&#39;, model=&#39;user&#39;)&#xA;        )&#xA;        SecurityFilter.objects.create(&#xA;            filter_conditions=&#34;{&#39;username&#39;: &#39;batman&#39;}&#34;,&#xA;            permission=make_joke,&#xA;            group=self.villains,&#xA;        )&#xA;&#xA;        users = UserProxy.objects.available(user=self.joker, permission=make_joke)&#xA;        victims = User.objects.filter(pk__in=[self.batman.pk])&#xA;&#xA;        self.assertEqual(set(users.values_list(&#39;pk&#39;, flat=True)), set(victims.values_list(&#39;pk&#39;, flat=True)))&#xA;&#xA;    def test_security_manager_no_perms(self):&#xA;        SecurityFilter.objects.all().delete()&#xA;&#xA;        users = UserProxy.objects.available(user=self.joker, permission=self.kill_and_rob)&#xA;&#xA;        self.assertEqual(set(users.values_list(&#39;pk&#39;, flat=True)), set())موفق و پیروز باشید . ❤️</description><category>MrYazdan</category><author>MrYazdan</author><pubDate>Sat, 15 Jul 2023 13:00:19 +0330</pubDate></item><item><title>ارث بری مدل ها در جنگو - قسمت اول ?</title><link>https://virgool.ir/@mryazdan/ارث-بری-مدل-ها-در-جنگو-قسمت-اول-mb4y6fr6fx37</link><description>Django model inheritanceتمام سند های متنشر شده در ویرگول ، در مخزن عمومی خود در گیتهاب موجود هستند : https://github.com/code-barg/daily-django-tips-fa سلام ?️ حال و احوالتون خوش، قراره امروز بریم سراغ ارث بری در مدل های جنگو و یه سری از نکات رو ازش یاد بگیریم، خب از اینجا شروع میکنیم:A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table.مدل دقیقا خود جنگو اینطور تعریفش میکنه : یک مدل منبع انفرادی و قطعی اطلاعات در مورد داده های شما است. مدل ها شامل فیلدها و رفتارهای ضروری داده هایی است که ذخیره می کنید. به طور کلی، هر مدل به یک جدول پایگاه داده میباشد !و حالا ORM جنگو یه لطفی در حق ما داشته و به ما قابلیت های جالبی در ارث بری مدل ها داده که امروز میخواهیم باهم در موردش بدونیم.ORM stands for Object Relational Mapping. Django allows us to add, delete, modify and query objects, using an API called ORM. Django provides a default admin interface that is required to perform operations like create, read, update and delete on the model directly.بله ، orm هم طبق توضیح مخفف Object Relational Mapping است. جنگو به ما این امکان را می دهد که با استفاده از یک API به نام ORM، اشیاء را اضافه، حذف، اصلاح و پرس و جو کنیم. جنگو یک رابط مدیریت پیش‌فرض ارائه می‌کند که برای انجام مستقیم عملیاتی مانند ایجاد، خواندن، به‌روزرسانی و حذف روی مدل لازم است.انواع ارث بری در مدل هاوقتی صحبت از ارث بری در مدل های جنگو میشه در اصل یعنی قراره کلاسی از یک یا چند کلاس دیگر که همه از django.db.models.Model ارث برده اند، ارث بری کند ! چه شیر تو شیری شد ! سخت ترین کار دنیا، توضیح مفهومی کدارث بری انتزاعی (abstract)به مثال زیر توجه کنید :class TimeStampedModel(models.Model):&#xA;    created_at = models.DateTimeField(auto_add_now=True)&#xA;    updated_at = models.DateTimeField(auto_now=True)&#xA;    &#xA;    class Meta:&#xA;        abstract = True&#xA;&#xA;&#xA;class Post(TimeStampedModel):&#xA;    title = models.CharField(max_length=128)&#xA;    ...&#xA;&#xA;&#xA;class Product(TimeStampedModel):&#xA;    name = models.CharField(max_length=128)&#xA;    ...ما اگر n کلاس دیگر مثل Product هم داشته باشیم ، باز هم میتونیم براحتی از کلاس انتزاعی خودمون بنام TimeStampedModel استفاده کنیمخب حالا این عملیات چه نتیجه ای داره ؟ قبل از هر چیز به نکته ای که داره در این کد دقت کنید : ‍‍‍class ...:&#xA;    ...&#xA;&#x9;&#xA;    class Meta:&#xA;        abstract = True&#xA;...برای ساخت Mixin مدل ها که در حقیقت بصورت انتزاعی هستند باید این قاعده را رعایت کنیم .خب حالا تعریفش کنیم :‌ مدل های انتزاعی مدل هایی هستند کهاصلا موجودیتی در دیتابیس به تنهایی ندارند (جدول TimeStampedModel نداریم )زمانی مفید هستند که می‌خواهید برخی از اطلاعات رایج را در تعدادی مدل دیگر قرار دهید.وقتی به عنوان یک کلاس پایه برای مدل‌های دیگر استفاده می‌شود، فیلدهای آن به کلاس فرزند اضافه می‌شود.بریم برای یک مثال عملی و جالب :from django.db import models  &#xA;  &#xA;  &#xA;class TimeStampedModel(models.Model):  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;TimeStampedModel  &#xA;&#x9;  &#xA;&#x9;An abstract base class model that provides self-managed &#34;created&#34; and  &#xA;&#x9;&#34;updated&#34; fields.  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;created = models.DateTimeField(auto_now_add=True)  &#xA;&#x9;updated = models.DateTimeField(auto_now=True)  &#xA;&#x9;  &#xA;&#x9;class Meta:  &#xA;&#x9;&#x9;abstract = True  &#xA;&#x9;&#x9;get_latest_by = &#39;created&#39; # default to get latest by created  &#xA;&#x9;&#x9;ordering = [&#39;-created&#39;] # default to order by created descending  &#xA;  &#xA;  &#xA;class LogicalDeleteModel(models.Model):  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;LogicalDeleteModel  &#xA;&#x9;  &#xA;&#x9;An abstract base class model that provides an &#34;is_deleted&#34; field.  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;is_deleted = models.BooleanField(default=False)  &#xA;&#x9;  &#xA;&#x9;class Meta:  &#xA;&#x9;&#x9;abstract = True  &#xA;  &#xA;  &#xA;class LogicalActiveModel(models.Model):  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;LogicalActiveModel  &#xA;&#x9;  &#xA;&#x9;An abstract base class model that provides an &#34;is_active&#34; field.  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;is_active = models.BooleanField(default=True)  &#xA;&#x9;  &#xA;&#x9;class Meta:  &#xA;&#x9;&#x9;abstract = True  &#xA;  &#xA;  &#xA;class Product(LogicalActiveModel, LogicalDeleteModel, TimeStampedModel):  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;Product model  &#xA;&#x9;  &#xA;&#x9;A product that can be purchased.  &#xA;&#x9;&#34;&#34;&#34;  &#xA;&#x9;name = models.CharField(max_length=128)  &#xA;&#x9;description = models.TextField()  &#xA;&#x9;price = models.DecimalField(max_digits=10, decimal_places=2)  &#xA;&#x9;quantity = models.IntegerField()  &#xA;&#x9;  &#xA;&#x9;def __str__(self):  &#xA;&#x9;&#x9;return self.nameما در این مثال ۴ مدل را پیاده سازی کرده ایم هر سه مدل اول در حقیقت BaseModel یا مدل های انتزاعی هستند، و مدل های دیگر که اینجا ما فقط از مدل Product استفاده کردیم مدل هایی هستند که از قابلیت های مدل های انتزاعی بهره می ببرند.به فایل migrations این مدل ها دقت کنید‌:from django.db import migrations, models  &#xA;  &#xA;class Migration(migrations.Migration):  &#xA;&#x9;initial = True  &#xA;&#x9;operations = [  &#xA;&#x9;&#x9;migrations.CreateModel(  &#xA;&#x9;&#x9;&#x9;name=&#39;Product&#39;,  &#xA;&#x9;&#x9;&#x9;fields=[  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;id&#39;, models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name=&#39;ID&#39;)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;created&#39;, models.DateTimeField(auto_now_add=True)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;updated&#39;, models.DateTimeField(auto_now=True)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;is_deleted&#39;, models.BooleanField(default=False)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;is_active&#39;, models.BooleanField(default=True)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;name&#39;, models.CharField(max_length=128)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;description&#39;, models.TextField()),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;price&#39;, models.DecimalField(decimal_places=2, max_digits=10)),  &#xA;&#x9;&#x9;&#x9;&#x9;(&#39;quantity&#39;, models.IntegerField()),  &#xA;&#x9;&#x9;&#x9;],  &#xA;&#x9;&#x9;&#x9;options={  &#xA;&#x9;&#x9;&#x9;&#x9;&#39;abstract&#39;: False,  &#xA;&#x9;&#x9;&#x9;},  &#xA;&#x9;&#x9;),  &#xA;&#x9;]متوجه شدید ؟ هیچ یک از مدل های abstract ما اصلا موجودیتی در دیتابیس ما ندارد ! ولی تمام خصوصیات هر یک از آن مدل ها روی مدل Product وجود دارد و در حقیقت ما از قواعد کد نویسی تمیز به همراه دسترسی و نظم بالا بهره برده ایم.نکته قابل توجه هم آنجاست که تمام متد (method) و پراپرتی (property) های کلاس های خود را دارند.خسته نباشید ?پینوشت ها:سطح این سند عمومی و آسان است ، پس در قسمت های بعدی سعی میکنیم ذره ذره سطح را ارتقا بدهیم.از دو abstract base class های مهم اینجا برای مثال در حد نمایش رو نمایی شده ، LogicalActive و LogicalDelete دو مدل انتزاعی پر استفاده و کارآمد هستند که بزودی برای هر کدوم جلسه ی مفصلی داریم.</description><category>MrYazdan</category><author>MrYazdan</author><pubDate>Sat, 15 Jul 2023 12:32:33 +0330</pubDate></item></channel></rss>