<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Ali Rahmani</title>
        <link>https://virgool.io/feed/@rhmni</link>
        <description>جوجه برنامه نویس</description>
        <language>fa</language>
        <pubDate>2026-06-19 22:55:19</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/740372/avatar/nort0L.jpg?height=120&amp;width=120</url>
            <title>Ali Rahmani</title>
            <link>https://virgool.io/@rhmni</link>
        </image>

                    <item>
                <title>صفحه نمایش یا همان سون سگمنت روی پی ال سی مدل DVP10SX چیست ؟</title>
                <link>https://virgool.io/@rhmni/%D8%B5%D9%81%D8%AD%D9%87-%D9%86%D9%85%D8%A7%DB%8C%D8%B4-%DB%8C%D8%A7-%D9%87%D9%85%D8%A7%D9%86-%D8%B3%D9%88%D9%86-%D8%B3%DA%AF%D9%85%D9%86%D8%AA-%D8%B1%D9%88%DB%8C-%D9%BE%DB%8C-%D8%A7%D9%84-%D8%B3%DB%8C-%D9%85%D8%AF%D9%84-dvp10sx-%DA%86%DB%8C%D8%B3%D8%AA-vzf2ubzqx3ln</link>
                <description>اگر به plc مدل DVPSX شرکت دلتا دقت کرده باشید ، کنار پورت RS-232 یک صفحه نمایش یا سون سگمنت وجود دارد.DVP10SX Deltaاز این سون سگمنت برای نمایش اعداد تا رقم و با دو فرمت دسیمال و هگزا دسیمال استفاده می شود.این مدل MPU دلتا یک رجیستر و سه فلگ خاص برای تنظیم کردن این سون سگمنت به ما می دهد.رجیستر D1196 : مقدار این رجیستر می تواند یک عدد صحیح ( integer ) باشد.فلگ M1196 : اگر فعال باشد عدد نمایش داده با فرمت هگزا دسیمال است در غیر این صورت با فرمت دسیمال است.فلگ M1197 : اگر فعال باشد ممیز سمت چپ فعال می شود.فلگ M1198 : اگر فعال باشد ممیز سمت راست فعال می شود.توجه : اگر عدد شما بیش از دو رقم باشد فقط دو رقم آخر سمت راست نمایش داده می شود.نمایش عدد 186 با فرمت هگزا دسیمال و فعال بودن فلگ M1198 نمایش عدد 186 با فرمت دسیمال و فعال بودن فلگ M1197</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Fri, 14 Apr 2023 00:22:37 +0330</pubDate>
            </item>
                    <item>
                <title>جریان شیفتی چیست ؟</title>
                <link>https://virgool.io/@rhmni/contactor-ith-qgzisaxfg5uy</link>
                <description>بر روی پلاک هر کنتاکتور جریان های مختلفی از جمله Ie ، Is ، Ith ، I1th و I2th نوشته شده است .جریان شیفتی یا همان ( Ith ) جریانی است که تیغه های کنتاکتور میتوانند در صورتی که کنتاکتور با یکبار اتصال در 8 ساعت کار ( یک شیفت کاری ) کند عبور دهند.جریان شیفتی معمولا بیشتر از جریان نامی کنتاکتور است.پلاک کنتاکتور 9 امپر مارک Lsبرای مثال تصویر بالا پلاک یک کنتاکتور 9 آمپر است که جریان شیفتی آن برابر با 25 آمپر است.یعنی اگر این کنتاکتور در هر شیفت کاری ( 8 ساعت ) فقط یک با متصل شود میتواند تا 25 آمپر را رد کند.</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Sat, 26 Mar 2022 16:26:02 +0430</pubDate>
            </item>
                    <item>
                <title>آموزش ماژولار کردن فایل settings در فریمورک Django</title>
                <link>https://virgool.io/@rhmni/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D9%85%D8%A7%DA%98%D9%88%D9%84%D8%A7%D8%B1-%DA%A9%D8%B1%D8%AF%D9%86-%D9%81%D8%A7%DB%8C%D9%84-settings-%D8%AF%D8%B1-%D9%81%D8%B1%DB%8C%D9%85%D9%88%D8%B1%DA%A9-django-puwt41g6xflg</link>
                <description>اگه با فریمورک محبوب و دوست داشتنی django ( جنگو ) کار کرده باشید حتما با فایل settings.py در روت اصلی پروژه آشنا هستید و کاربرد اون را میدونید.جنگو از معروفترین فریورک های وب زبان پایتونوقتی با دستور : $ django-admin startproject proj-name یک پروژه جنگویی جدید میسازیم فایل settings.py به صورت زیر است : ( بسته به ورژن جنگو ممکن است کمی  با متن زیر متفاوت باشد )&amp;quot&amp;quot&amp;quot
Django settings for proj-name project.
Generated by &#039;django-admin startproject&#039; using Django 3.2.4.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
&amp;quot&amp;quot&amp;quot

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / &#039;subdir&#039;.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = &#039;django-insecure-tsjcndnvd;kbmd;mdajj!z9i*&amp;$&amp;&amp;f1k5h!f_gn7#bb2(ud&#039;

# SECURITY WARNING: don&#039;t run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    &#039;django.contrib.admin&#039;,
    &#039;django.contrib.auth&#039;,
    &#039;django.contrib.contenttypes&#039;,
    &#039;django.contrib.sessions&#039;,
    &#039;django.contrib.messages&#039;,
    &#039;django.contrib.staticfiles&#039;,
]

MIDDLEWARE = [
    &#039;django.middleware.security.SecurityMiddleware&#039;,
    &#039;django.contrib.sessions.middleware.SessionMiddleware&#039;,
    &#039;django.middleware.common.CommonMiddleware&#039;,
    &#039;django.middleware.csrf.CsrfViewMiddleware&#039;,
    &#039;django.contrib.auth.middleware.AuthenticationMiddleware&#039;,
    &#039;django.contrib.messages.middleware.MessageMiddleware&#039;,
    &#039;django.middleware.clickjacking.XFrameOptionsMiddleware&#039;,
]

ROOT_URLCONF = &#039;proj-name.urls&#039;

TEMPLATES = [
    {
        &#039;BACKEND&#039;: &#039;django.template.backends.django.DjangoTemplates&#039;,
        &#039;DIRS&#039;: [BASE_DIR / &#039;templates&#039;]
        ,
        &#039;APP_DIRS&#039;: True,
        &#039;OPTIONS&#039;: {
            &#039;context_processors&#039;: [
                &#039;django.template.context_processors.debug&#039;,
                &#039;django.template.context_processors.request&#039;,
                &#039;django.contrib.auth.context_processors.auth&#039;,
                &#039;django.contrib.messages.context_processors.messages&#039;,
            ],
        },
    },
]

WSGI_APPLICATION = &#039;proj-name.wsgi.application&#039;

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    &#039;default&#039;: {
        &#039;ENGINE&#039;: &#039;django.db.backends.sqlite3&#039;,
        &#039;NAME&#039;: BASE_DIR / &#039;db.sqlite3&#039;,
    }
}

# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.UserAttributeSimilarityValidator&#039;,
    },
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.MinimumLengthValidator&#039;,
    },
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.CommonPasswordValidator&#039;,
    },
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.NumericPasswordValidator&#039;,
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = &#039;en-us&#039;

TIME_ZONE = &#039;Asia/Tehran&#039;

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = &#039;/static/&#039;

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = &#039;django.db.models.BigAutoField&#039;مسلما در حین پروژه تنظیمات زیادی به به این فایل اضافه میشه که بعضی از اون ها ثابت و بعضی بسته به محیط development یا production متفاوت اند .( مانند متغیر های   DEBUG  و  ALLOWED_HOSTS )در روت اصلی پروژه ( کنار فایل settings.py ) یه دایرکتوری به نام settings میسازیم و چهار فایل زیر را هم داخلش میسازیم :__init__.py
base.py
production.py
development.pyالان روت اصلی پروژه ما به این صورت هست :
├── proj-name/
│   ├── __init__.py
│   ├── settings/
│   │   ├── base.py
│   │   ├── development.py
│   │   ├── __init__.py
│   │   └── production.py
│   ├── urls.py
│   └── wsgi.py
└── manage.pyحالا فایل base.py را ویرایش میکنیم و اون تنظیماتی از پروژه را که در هر دو حالت development و production ثابت هستند را داخلش مینویسیم :from pathlib import Path

# Build paths inside the project like this: BASE_DIR / &#039;subdir&#039;.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = &#039;django-insecure-tsjcndnvd;kbmd;mdajj!z9i*&amp;$&amp;&amp;f1k5h!f_gn7#bb2(ud&#039;


# Application definition

INSTALLED_APPS = [
    &#039;django.contrib.admin&#039;,
    &#039;django.contrib.auth&#039;,
    &#039;django.contrib.contenttypes&#039;,
    &#039;django.contrib.sessions&#039;,
    &#039;django.contrib.messages&#039;,
    &#039;django.contrib.staticfiles&#039;,
]

MIDDLEWARE = [
    &#039;django.middleware.security.SecurityMiddleware&#039;,
    &#039;django.contrib.sessions.middleware.SessionMiddleware&#039;,
    &#039;django.middleware.common.CommonMiddleware&#039;,
    &#039;django.middleware.csrf.CsrfViewMiddleware&#039;,
    &#039;django.contrib.auth.middleware.AuthenticationMiddleware&#039;,
    &#039;django.contrib.messages.middleware.MessageMiddleware&#039;,
    &#039;django.middleware.clickjacking.XFrameOptionsMiddleware&#039;,
]

ROOT_URLCONF = &#039;proj-name.urls&#039;

TEMPLATES = [
    {
        &#039;BACKEND&#039;: &#039;django.template.backends.django.DjangoTemplates&#039;,
        &#039;DIRS&#039;: [BASE_DIR / &#039;templates&#039;]
        ,
        &#039;APP_DIRS&#039;: True,
        &#039;OPTIONS&#039;: {
            &#039;context_processors&#039;: [
                &#039;django.template.context_processors.debug&#039;,
                &#039;django.template.context_processors.request&#039;,
                &#039;django.contrib.auth.context_processors.auth&#039;,
                &#039;django.contrib.messages.context_processors.messages&#039;,
            ],
        },
    },
]

WSGI_APPLICATION = &#039;proj-name.wsgi.application&#039;


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.UserAttributeSimilarityValidator&#039;,
    },
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.MinimumLengthValidator&#039;,
    },
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.CommonPasswordValidator&#039;,
    },
    {
        &#039;NAME&#039;: &#039;django.contrib.auth.password_validation.NumericPasswordValidator&#039;,
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = &#039;en-us&#039;

TIME_ZONE = &#039;Asia/Tehran&#039;

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = &#039;/static/&#039;

STATICFILES_DIRS = [
    BASE_DIR / &amp;quotstatic&amp;quot
]

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = &#039;django.db.models.BigAutoField&#039;تنظیماتی که بالا میبینید همگی تنظیماتی هستند که در طول کل پروژه ثابت هستند و برای محیط های مختلف نیازی به تغیر ندارند.فایل development.py ویژه تنظیماتی از پروژه است که فقط برای محیط develop هستند :from .base import *
DEBUG = True

ALLOWED_HOSTS = []

DATABASES = {
    &#039;default&#039;: {
        &#039;ENGINE&#039;: &#039;django.db.backends.sqlite3&#039;,
        &#039;NAME&#039;: BASE_DIR / &#039;db.sqlite3&#039;,
    }
}همچنین در فایل production.py تنظیماتی را قرار میدیم که برای محیط production یا همون دپلوی پروژه هستند :from .base import *
DEBUG = False

ALLOWED_HOSTS = [
    &#039;www.test.com&#039;,
    &#039;test.com&#039;,
]

STATIC_ROOT = &#039;static_root&#039;

DATABASES = {
    &#039;default&#039;: {
        &#039;ENGINE&#039;: &#039;django.db.backends.postgresql&#039;,
        &#039;NAME&#039;: &#039;your_database_name&#039;,
        &#039;USER&#039;: &#039;your_database_user&#039;,
        &#039;PASSWORD&#039;: &#039;your_password&#039;,
        &#039;HOST&#039;: &#039;your_host&#039;,
        &#039;PORT&#039;: &#039;your_port&#039;,
    }
}
اگه دقت کرده باشد در دو فایل بالا اول هر خط فایل base.py را ایمپورت کرده ایم این کار برای دسترسی به بقیه تنظیمات پروژه است چون باید به جنگو بگیم که فایل settings.py تغیر کرده و آدرس یکی از دو فایل  development.py و  production.py بهش بدیم.برای اینکه به جنگو بفهمونیم که فایل settings.py ما تغیر کرده دو روش وجود داره :روش اولاز طریق ترمینال هنگام ران کردن پروژه :$ python manage.py migrate --settings=proj-name.settings.productionروش دوماز طریق فایل manage.py پروژه :#!/usr/bin/env python
&amp;quot&amp;quot&amp;quotDjango&#039;s command-line utility for administrative tasks.&amp;quot&amp;quot&amp;quot
import os
import sys


def main():
    &amp;quot&amp;quot&amp;quotRun administrative tasks.&amp;quot&amp;quot&amp;quot
    os.environ.setdefault(&#039;DJANGO_SETTINGS_MODULE&#039;, &#039;proj-name.settings.development&#039;)   # &lt;-- Change here!
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            &amp;quotCouldn&#039;t import Django. Are you sure it&#039;s installed and &amp;quot
            &amp;quotavailable on your PYTHONPATH environment variable? Did you &amp;quot
            &amp;quotforget to activate a virtual environment?&amp;quot
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == &#039;__main__&#039;:    
    main()</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Wed, 23 Jun 2021 12:00:59 +0430</pubDate>
            </item>
                    <item>
                <title>ساختار  Switch / Case در پایتون</title>
                <link>https://virgool.io/@rhmni/%D8%B3%D8%A7%D8%AE%D8%AA%D8%A7%D8%B1-switch-case-%D8%AF%D8%B1-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-o9n6fl4fg4bb</link>
                <description>دستور switch / case یه ساختاری که تقریباً در اکثر زبان های برنامه نویسی وجود داره .کاربردش یه جورایی تو مایه های if / else با این تفاوت که توی شرط های طولانی استفاده از switch / case کد تمیز تر و کوتاه تری را به ما میده.مثالی از  switch / case در جاوا اسکریپتاگه بخواهیم مثال بالا را توی پایتون بنویسیم باید به صورت زیر بنویسیم :همونطور که می بینید اگه بخواهیم به این شکل بنویسیم کدمون طولانی میشه  ، ولی میشه این برنامه را طور دیگه ای با کد کمتر نوشت.توی زبان پایتون عبارت switch / case به صورت مستقیم وجود نداره ، اما میشه با استفاده از دیکشنری ها در پایتون چیزی شبیه به اون ها را پیاده سازی کرد.برای اینکار اول یه فانکشن مینویسیم که یه متغیر را به عنوان ورودی دریافت میکنه و یه دیکشنری خالی را برای ما بر میگردونه:حالا اون مقادیری که انتظار داریم متغیر ما داشته باشه را به عنوان کلید ها و مقدار های دیکشنری قرار میدیم:حالا با استفاده از متد ()get که برای دیکشنری ها موجوده ( اگه با این متد آشنایی ندارید به آخر پست مراجعه کنید  ) اون کلیدی که میخاهیم مقدارش را میگیریم و برمیگردونیم:این هم کد تصویر بالا اگه حالش را ندارید بنویسیدش و میخواهید برای تست کردن کپی کنید ?def test(grade):
    return {
        &#039;A&#039;: &#039;This is A&#039;,
        &#039;B&#039;: &#039;This is B&#039;,
        &#039;C&#039;: &#039;This is C&#039;,
        &#039;D&#039;: &#039;This is D&#039;,
        &#039;F&#039;: &#039;This is F&#039;,
    }.get(grade, f&#039;{grade} is not a grade!&#039;)  متد  ()get  پایتوناین متد برای دیکشنری ها توی پایتون موجوده و دو مقدار را از ما میگیره.مقدار اول اون کلیدی از اون دیکشنری هست که ما بهش نیاز داریم ،  مقدار دوم ، اگه اون کلید توی اون دیکشنری موجود نبود برای ما برگردونده میشه و به ما نشون میده.این مقدار دلخواه هست و اگه قرار ندیم به صورت پیش فرض به ما None برمیگردونه.</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Fri, 30 Apr 2021 18:50:07 +0430</pubDate>
            </item>
                    <item>
                <title>ذن ( Zen ) پایتون چیست ؟</title>
                <link>https://virgool.io/@rhmni/%D8%B0%D9%86-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%DA%86%DB%8C%D8%B3%D8%AA-hpu95wqw89dg</link>
                <description>Zen Of Pythonذن پایتون چیست ؟ذن پایتون مجموعه ای از 20 اصل بنیادین و تأثیرگذار بر طراحی زبان Python است که توسط Tim Peters در سال 1999 میلادی نوشته شده است.نکته ای جالب در رابطه با ذن پایتون وجود دارد که تنها 19 اصل از 20 اصل بیان شده است و Tim Peters اصل بیستم را برای خالق زبان پایتون یعنی Guido van Rossum کنار گذاشته است ولی تا این لحظه اصل بیستم توسط Guido van Rossum بیان نشده است.برای مشاهده 19 اصل ذن پایتون میتونید وارد برنامه پایتونی خودتون بشید و دستور :import thisرا وارد کنید ، حالا اگه برنامه خودتون را اجرا کنید نتیجه زیر را میگیرید :  The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren&#039;t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you&#039;re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it&#039;s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let&#039;s do more of those!ترجمه 19 اصل ذن پایتون :زیبا بهتر از زشت است.بیان صریح بهتر از ضمنی است.ساده بهتر از پیچیده ‌است.پیچیده بهتر از افتضاح است.مستقیم و صاف بهتر از تو در تو است.پراکنده بهتر از متراکم است.خوانایی مهم است.موارد ویژه به اندازه‌ای ویژه نیستند که به خاطر آن‌ها بتوان قوانین را شکست.گرچه عملی بودن خلوص را از بین می‌ برد.خطاها هرگز نباید با سکوت رد شوند.مگر اینکه صریحاً خاموش شده باشند.در رو به رو شدن با ابهام، از وسوسه حدس زدن دوری کن.برای انجام این کار باید یک (ترجیها یک) روش واضح وجود داشته باشد.اگر چه ممکن است این روش در ابتدا واضح و آشکار نباشد مگر اینکه شما هلندی باشید.حالا بهتر از هرگز است.اگر چه «هرگز» اغلب بهتر از «همین حالا» است.اگر تشریح پیاده‌سازی آن سخت باشد، ایده بدی است.اگر تشریح پیاده‌سازی آن آسان باشد، ممکن است ایده خوبی باشد.فضای نام‌ها ایده بی‌نظیری هستند، بیایید بیشتر از آن‌ها استفاده کنیم!منبع  :  Python Trick Book</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Thu, 25 Mar 2021 11:37:50 +0430</pubDate>
            </item>
                    <item>
                <title>ساخت سبد خرید در جنگو</title>
                <link>https://virgool.io/@rhmni/%D8%B3%D8%A7%D8%AE%D8%AA-%D8%B3%D8%A8%D8%AF-%D8%AE%D8%B1%DB%8C%D8%AF-%D8%AF%D8%B1-%D8%AC%D9%86%DA%AF%D9%88-i5dvugzj6x4z</link>
                <description> مطمعناً یکی از مهمترین قسمت های یک سایت فروشگاهی طراحی قسمت سبد خرید آن است.برای ایجاد سبد خرید در جنگو روش های متفاوتی وجود دارد.در این آموزش میخواهیم با استفاده از مدل های جنگو سبد خرید خودمون را طراحی کنیم.برا مدل محصولات خودمون از مدل زیر استفاده میکنیم :class Product(models.Model):
     title = models.CharField(max_length=150)                     
     description = models.TextField()
     price = models.PositiveBigIntegerField()  
     image = models.ImageField()

     def __str__(self):
          return self.titleحالا نیاز به یه مدل دیگه به اسم سبد خرید داریم تا هر کاربر بتونه یک سری از محصولات مورد نیازش را به اون اضافه کنه و عملیات پرداخت را انجام بده :class Cart(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    is_paid = models.BooleanField(default=False)

    @property
    def total_price(self):
    total = 0
    for cart_item in self.cartitems.all():
         total += (cart_item.price * cart_item.quantity)
    return int(total)

    def __str__(self):
    return self.user.usernameحتما براتون الان سوال شده که چرا بین مدل محصولات و سبد خرید هیچ رابطه ای برقرار نیست؟برای وصل کردن سبد خرید به محصولات نیاز به یک مدل دیگه ای به شکل زیر داریم:class CartItem(models.Model):
     cart = models.ForeignKey(Cart, on_delete=models.CASCADE, 
     related_name=&#039;cartitems&#039;)
     product = models.ForeignKey(Product, on_delete=models.CASCADE)
     price = models.PositiveIntegerField() 
     quantity = models.PositiveSmallIntegerField()

     @property 
     def total_price(self):
          return int(self.price * self.quantity)  

     def __str__(self):
          return self.product.titleممکنه بگید که چرا باید یه مدل دیگه بین سبد خرید و محصولات باشه و چرا سبد خرید و محصولات را مستقیم به هم وصل نمی کنیم؟مدل رابط ما (CartItem) باید یکسری اطلاعات دیگه ای از جمله تعداد اون محصول ، قیمت اون محصول هنگام خرید و ... را ذخیره کنه ، پس برای ذخیره این اطلاعات به این مدل میانی نیاز داریم.ممکنه با شکل زیر بهتر قضیه را متوجه بشید :توضیح فیلد های مدل CartItem :برای اینکه بدونیم این ابجکت برای کدوم سبد خرید هست. { cart }برای اینکه بدونیم این این ابجکت برای کدوم محصول است. { product }این فیلد قیمت محصول را توی خودش ذحیره میکنه و ثابت نگه میداره تا اگه بعداً قیمت اون محصول بیشتر شد بدونید که این محصول قبلا به چه قیمتی فروش رفته. { price }این فیلد مقداری را توی خودش ذخیره میکنه که نشون میده کاربر قصد خرید چه تعداد از اون محصول را داشته. { quantity }این متد تعداد را در قیمت ضرب میکنه و قیمت کل را به ما میده. { total_price }توضیح فیلد های مدل Cart :برای اینکه بدونیم این سبد خرید برای کدوم کاربر هست. { user }برای اینکه بدونیم این سبد خرید پرداخت شده است یا نه { is_paid }این متد قیمت کل همه  cartitem های اون سبد را جمع میکنه و قیمت کل سبد خرید ( اون مبلغی که کاربر باید پرداخت کنه ) را به ما میده. { total_price }راه و روش های زیادی از جمله استفاده از سشن ها ( sessions ) برای ایجاد سبد خرید وجود داره که هر کدوم مزایا و معایب خودشون را دارند.مدل های بالا به صورت ساده ترین شکل ممکن برای آموزش تعریف شدند شما به دلخواه خودتون میتونید فیلد هایی را به اونها اضافه یا کم کنید.</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Tue, 23 Mar 2021 20:35:30 +0430</pubDate>
            </item>
                    <item>
                <title>شخصی سازی ارور 404 ( Page not found ) در جنگو</title>
                <link>https://virgool.io/@rhmni/%D8%B4%D8%AE%D8%B5%DB%8C-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%A7%D8%B1%D9%88%D8%B1-404-%D8%AF%D8%B1-%D8%AC%D9%86%DA%AF%D9%88-wrtafb7ipbdt</link>
                <description>توی این آموزش میخوام بهتون بگم چطور صفحه 404 جنگو را شخصی سازی کنید و صفحه دلخواه خودتون را به کاربر نشون بدید.وقتی یه آدرسی که در urlpatterns های ما وجود نداشته باشه (مثل : http://127.0.0.1:8000/fdgfm ) و ما وارد اون آدرس بشیم جنگو صفحه ای مشابه صفحه زیر را به ما نشون میده :اما این صفحه ای نیست که جنگو به کاربران ما نشون میده برای دیدن اون صفحه باید اول دو مقدار را در فایل settings.py پروژه تون تغییر بدید :# settings.pyDEBUG = TrueALLOWED_HOSTS = []تغییر بدید به :DEBUG = FalseALLOWED_HOSTS = [&#039;127.0.0.1&#039;]حالا دوباره وارد آدرس http://127.0.0.1:8000/fdgfm بشید این بار صفحه زیر را میبینید و دقیقا این همون صفحه ای است که بقیه کاربران هم می بینید :دو روش برای تغییر صفحه 404 پیش فرض جنگو وجود داره که روش اول راحت تر از دومی هست :روش اول : کافیه برای تغییر این صفحه یه فایل html به اسم 404.html ( دقت کنید که حتما باید اسمش همین باشه و گرنه همون صفحه پیش فرض را براتون میاره ) توی یکی از دایرکتوری های templates که توی پروژه تون وجود داره بسازید بعد از اون خود جنگو متوجه میشه و این صفحه را جایگزین قبلی میکنه.روش دوم : این روش یکم سخت تر از روش اول هست اما کاربردش برای زمانی هست شما میخواهید یک دیتایی را توی این صفحه به کاربر نشون بدید :باید وارد یکی از فایل ها پروژه تون به اسم views.py بشید و کد زیر را داخلش قرار بدید :# views.pydef not_found(request, exception):
     return render(request,&#039;404.html&#039;)به حالا وارد فایل urls.py بشید و این کد را به کد هاتون اضافه کنید ( فقط خط چهارم را اضافه کنید ) :# urls.pyurlpatterns = [
    path( &#039; admin/&#039;,  admin.site.urls),
] 
handler404 = &#039;myapp.views.not_found&#039;حالا اگه دوباره وارد آدرس http://127.0.0.1:8000/fdgfm بشید میبینید که صفحه دلخواه شما را باز هم براتون اورده.برای بقیه اررور ها مثل 403 ، 500 و ... هم باید به همین روش عمل کنید و به جای 404 عدد 500 یا 403 را قرار بدید.</description>
                <category>Ali Rahmani</category>
                <author>Ali Rahmani</author>
                <pubDate>Tue, 23 Mar 2021 12:21:11 +0430</pubDate>
            </item>
            </channel>
</rss>