وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

روابط مدل بازگشتی در جنگو

0 10
زمان لازم برای مطالعه: 7 دقیقه


نیاز به روابط بازگشتی

بارها در توسعه برنامه های کاربردی وب مدرن وجود دارد که در آن الزامات تجاری ذاتاً روابطی را توصیف می کنند که بازگشتی. یکی از نمونه های شناخته شده چنین قانون تجاری در توصیف کارمندان و رابطه آنها با مدیرانشان است که آنها نیز کارمند هستند. به ماهیت دایره ای آن بیانیه توجه کنید. این دقیقاً همان چیزی است که از یک رابطه بازگشتی استفاده می شود. در این مقاله ما یک نسخه آزمایشی استخوان خالی در جنگو از یک برنامه فهرست کارمندان منابع انسانی (HR) با این رابطه بازگشتی بین کارمندان و مدیران ایجاد خواهیم کرد.

کد این مقاله را می توانید در اینجا پیدا کنید این مخزن GitHub.

راه اندازی ساختار پروژه جنگو

برای پیشبرد پروژه جنگو، باید یک پروژه جدید ایجاد کنید python محیط مجازی (ترجیحا Python3). اگر با محیط های مجازی آشنایی ندارید این مقاله را ببینید. هنگامی که وارد محیط مجازی فعال شده خود شوید، pip جنگو را نصب کنید

(venv) $ pip install django

با نصب جنگو، می‌توانید از ابزارهای مدیریت جنگو برای تولید boilerplate پروژه، که ما آن را «webapp» می‌نامیم، استفاده کنید. می توانید در مقاله ما، Flask vs Django، درباره راه اندازی پروژه جنگو اطلاعات بیشتری کسب کنید.

(venv) $ django-admin startproject webapp

اکنون cd به دایرکتوری جدید برنامه وب، تا بتوانیم از مجموعه دیگری از ابزارهای جنگو از طریق manage.py اسکریپت ما از این برای ایجاد برنامه کاربردی پروژه خود استفاده می کنیم که نام آن را “hrmgmt” می گذاریم. با این کار دایرکتوری دیگری به نام “hrmgmt” ایجاد می شود که کد این برنامه در آن قرار می گیرد.

(venv) $ cd webapp
(venv) $ python manage.py startapp hrmgmt

آخرین بخش راه اندازی پروژه شامل اطلاع رسانی پروژه (برنامه وب) در مورد آن است hrmgmt کاربرد. که در webapp/settings.py بخشی را با نظر “تعریف برنامه” در بالای لیست پیدا کنید INSTALLED_APPS و یک ورودی از را اضافه کنید hrmgmt.apps.HrmgmtConfig، مانند:



INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hrmgmt.apps.HrmgmtConfig'
)

پیکربندی مسیرها

در جنگو دایرکتوری که با نام پروژه مطابقت دارد، “webapp” در مورد ما، جایی است که تنظیمات اصلی و نقطه ورود به مسیرهای برنامه مدیریت داخلی و هر برنامه سفارشی اضافی وجود دارد. بنابراین در webapp/urls.py از کد زیر برای هدایت تمام مسیرهای با پیشوند “/hr” به مسیر استفاده کنید hrmgmt کاربرد.


from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = (
    url(r'^admin/', admin.site.urls),
    url(r'^hr/', include('hrmgmt.urls'))
)

در عرف hrmgmt برنامه یک فایل جدید با نام ایجاد می کند urls.py و کد زیر را قرار دهید. این نمایه ای را مشخص می کند که لیستی از همه کارمندان را برمی گرداند. کد زیر از یک عبارت منظم استفاده می کند تا نشان دهد که وقتی مسیر “/hr/” از سرور ما درخواست می شود، تابع view با نام index باید درخواست را رسیدگی کند و پاسخی را برگرداند.


from django.conf.urls import url

import views

urlpatterns = (
    
    url(r'^$', views.index, name='index')
)

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

کلنگ زدن تابع نمای شاخص

حال بیایید موارد فوق را پیاده سازی کنیم index مشاهده تابع برای رسیدگی به درخواست‌های مسیر “/hr/” و بازگرداندن یک پاسخ متنی به ما اطلاع دهد که موارد را به درستی پیکربندی کرده‌ایم. بعداً باز خواهیم گشت و این را به یک عملکرد نمای مناسب‌تر برای فهرست کردن کارمندان خود تبدیل می‌کنیم.

که در hrmgmt/views.py کد زیر را شامل شود:


from django.http import HttpResponse

def index(request):
    response = "My List of Employees Goes Here"
    return HttpResponse(response)

در دایرکتوری برنامه وب، سرور توسعه جنگو را روشن کنید و آزمایش کنید که عملکرد مسیر و نمایش خود را به درستی پیکربندی کرده ایم:

(venv) $ python manage.py runserver

حالا به مرورگر خود بروید و وارد شوید http://localhost:8000/hr/ و شما باید یک پاسخ متنی با عنوان “فهرست من از کارمندان اینجا می رود” را ببینید.

طراحی کلاس های مدل ما

بالاخره به قسمت خوبش می رسیم! در این بخش، کلاس‌های مدل خود را تعریف می‌کنیم که به جداول پایگاه داده تبدیل می‌شوند و همه با نوشتن کد پایتون انجام می‌شوند. یا استفاده از چیزی که افراد دات نت به عنوان رویکرد “اول کد” برای طراحی پایگاه داده ابداع کرده اند.

که در hrmgmt/models.py در کد زیر قرار دهید:


from django.db import models

class Employee(models.Model):
    STANDARD = 'STD'
    MANAGER = 'MGR'
    SR_MANAGER = 'SRMGR'
    PRESIDENT = 'PRES'

    EMPLOYEE_TYPES = (
        (STANDARD, 'base employee'),
        (MANAGER, 'manager'),
        (SR_MANAGER, 'senior manager'),
        (PRESIDENT, 'president')
    )

    role = models.CharField(max_length=25, choices=EMPLOYEE_TYPES)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    manager = models.ForeignKey('self', null=True, related_name='employee')

    def __str__(self):
        return "<Employee: {} {}>".format(self.first_name, self.last_name)

    def __repr__(self):
        return self.__str__()

در این چند خط کد چیزهای زیادی وجود دارد، بنابراین اجازه دهید آنها را تجزیه کنیم. اولین چیزی که باید به آن توجه کرد این است که یک کلاس پایتون نامگذاری شده است Employee در حال اعلام است که از آن به ارث می برد django.db.models.Model کلاس این ارث می دهد Employee طبقه بندی قابلیت دسترسی به پایگاه داده از طریق ORM جنگو.

در ادامه تعاریف چهار فیلد کلاس که ثابت هستند (STANDARD، MANAGER، SR_MANAGER، PRESIDENT) و استفاده از آنها برای تعریف بیشتر ثابت فیلد کلاس چندگانه است. اینها به نوعی مانند فهرست هایی هستند که نقش های مختلفی را که یک کارمند می تواند بر عهده بگیرد را مشخص می کند. در واقع، ثابت چند تایی به تعریف فیلد کلاس نقش‌ها منتقل می‌شود تا مشخص کند که کلاس باید چه مقادیری را بپذیرد.

بعد first_name و last_name فیلدهای کلاس به عنوان فیلدهای کاراکتری با حداکثر طول 100 کاراکتر تعریف می شوند.

میدان نهایی تعریف شده شاید پرمعنی ترین زمینه باشد، یعنی manager رشته. این یک کلید خارجی است که رابطه بازگشتی بین کارکنان و مدیران آنها را تعریف می کند. این بدان معنی است که ستون شناسه عدد صحیح افزایش خودکار ضمنی که جنگو ایجاد می کند روی مدل هایی که از آنها به ارث می رسد django.db.models.Model به عنوان یک مقدار کلید خارجی برای همان کلاس (یا جدول) در دسترس خواهد بود.

این مورد مورد استفاده ما را برآورده می کند که می تواند به این صورت بیان شود: “یک کارمند ممکن است فقط یک مدیر مستقیم داشته باشد یا هیچ مدیری در مورد رئیس جمهور نداشته باشد، اما یک کارمند ممکن است کارمندان مختلفی را مدیریت کند”. با مشخص کردن self به عنوان اولین پارامتر از model.ForeignKey جنگو این را به عنوان یک رابطه بازگشتی تنظیم می کند. سپس با مشخص کردن null=True این مدل به کارمندی بدون مدیر اجازه می دهد که در مثال ما کسی است که نماینده رئیس جمهور است.

در زیر یک نمودار ERD از رابطه بازگشتی که ما تعریف کرده ایم آورده شده است.

روابط مدل بازگشتی در جنگو

انتقال تعریف کلاس ما به پایگاه داده

برای تبدیل کدی که برای تعریف کلاس Employee خود به DDL SQL استفاده کردیم، دوباره از یک ابزار جنگو استفاده خواهیم کرد که از طریق manage.py اسکریپت و در مجموع به عنوان مهاجرت شناخته می شود.

البته در خط فرمان، در محیط مجازی ما، موارد زیر را برای ایجاد جداول پیش‌فرض که همه برنامه‌های جنگو از آن استفاده می‌کنند، اجرا کنید. به طور پیش فرض، این پایگاه داده یک است SQLite پایگاه داده در root پوشه پروژه.

(venv) $ python manage.py migrate

پس از تکمیل، می‌توانیم یک انتقال جدید ایجاد کنیم که جدولی را که ما را پشتیبان می‌کند، تعریف می‌کند Employee کلاس این کار را با صدور دستورات زیر انجام دهید و مطمئن شوید که خروجی را مطابق شکل زیر مشاهده می کنید:

(venv) $ python manage.py makemigrations
(venv) $ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, hrmgmt, sessions
Running migrations:
  Applying hrmgmt.0001_initial... OK

با اجرای دستور زیر می توانید DDL SQL واقعی را که جدول را ایجاد می کند مشاهده کنید:

(venv) $ python manage.py sqlmigrate hrmgmt 0001

BEGIN;
--
-- Create model Employee
--
CREATE TABLE "hrmgmt_employee" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "role" varchar(25) NOT NULL, "first_name" varchar(100) NOT NULL, "last_name" varchar(100) NOT NULL, "manager_id" integer NULL REFERENCES "hrmgmt_employee" ("id"));
CREATE INDEX "hrmgmt_employee_manager_id_43028de6" روی "hrmgmt_employee" ("manager_id");
COMMIT;

کاوش مدل‌ها با پوسته جنگو

در خط فرمان دستور زیر را وارد کنید تا مفسر با زمینه برنامه جنگو ما از پیش بارگذاری شده در REPL راه اندازی و اجرا شود:

(venv) $ python manage.py shell

اکنون که مفسر پایتون راه اندازی و اجرا می شود دستورات زیر را وارد کنید:

>>> from hrmgmt.models import Employee
>>> janeD = Employee.objects.create(first_name='Jane', last_name='Doe', role=Employee.PRESIDENT)
>>> johnD = Employee.objects.create(first_name='John', last_name='Doe', role=Employee.MANAGER, manager=janeD)
>>> joeS = Employee.objects.create(first_name='Joe', last_name='Scho', role=Employee.STANDARD, manager=johnD)
>>> johnB = Employee.objects.create(first_name='John', last_name='Brown', role=Employee.STANDARD, manager=johnD)

کد بالا چهار کارمند ساختگی ایجاد می کند. جین دو رئیس جمهور است. سپس جان دو نقش مدیری دارد و توسط مادرش جین دو مدیریت می شود (بله، به وضوح در اینجا نوعی خویشاوندی وجود دارد). تحت نظارت جان دو جو اشمو و جان براون هستند که هر دو نقش یک کارمند استاندارد یا پایه را دارند.

ما می توانیم زمینه روابط خود را آزمایش کنیم employee با بازرسی خروجی تماس employee روی ما johnD متغیر:

>>> johnD.employee.all()
<QuerySet (<Employee: Joe Scho>, <Employee: John Brown>)>

و همچنین با janeD متغیر:

>>> janeD.employee.all()
<QuerySet (<Employee: John Doe>)>

به طور مشابه، ما می خواهیم فیلد مدیر خود را آزمایش کنیم تا از عملکرد مطلوب آن مطمئن شویم:

>>> johnD.manager
<Employee: Jane Doe>

عالی! به نظر می رسد همه چیز همانطور که انتظار می رود کار می کند.

تنظیم نمای ما

در همان دایرکتوری ما hrmgmt دایرکتوری ایجاد یک دایرکتوری دیگر به نام templates. سپس در داخل templates دایرکتوری ایجاد یک دایرکتوری دیگر به نام hrmgmt. در نهایت در داخل hrmgmt/templates/hrmgmt دایرکتوری، یک فایل HTML به نام بسازید index.html. در این فایل است که ما کدی را برای ایجاد لیست کارمندان خود می نویسیم.

در کد زیر کپی و پیست کنید:


<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Employee Listing</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <h1>Employee Listing</h1>
                </div>
            </div>
            <div class="row">
                <dov class="col-md-12">
                    <table class="table table-striped">
                        <thead class="thead-inverse">
                            <tr>
                                <th>Employee ID</th>
                                <th>First Name</th>
                                <th>Last Name</th>
                                <th>Role</th>
                                <th>Manager</th>
                            </tr>
                        </thead>
                        <tbody class='table-striped'>
                            {% for employee in employees %}
                            <tr>
                                <td>{{ employee.id }}</td>
                                <td>{{ employee.first_name }}</td>
                                <td>{{ employee.last_name }}</td>
                                <td>{{ employee.get_role_display }}</td>
                                <td>{% if employee.manager %}{{ employee.manager.first_name }} {{ employee.manager.last_name }}{% endif %}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </dov>
            </div>
        </div>
        <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
    </body>
</html>

این فایل با نام a قالب در چارچوب وب جنگو. الگوها طرحی را برای HTML قابل تکرار نشان می دهند که به صورت پویا بر اساس تولید می شود روی داده هایی که به آن ارسال می شود. در مورد ما، داده‌هایی که به الگوی «شاخص» ما ارسال می‌شوند، فهرست کارمندان ما را نشان می‌دهند.

برای ارائه الگوی خود باید چند تغییر در عملکرد view خود ایجاد کنیم. یعنی ما نیاز داریم import را render تابع کمکی از میانبرهای جنگو، سپس به جای بازگشت HttpResponse ما یک تماس به render، عبور در request شی، مسیر الگوی ما، و دیکشنری حاوی داده‌هایی که باید به الگوی ما ارسال شود.


from django.shortcuts import render

from .models import Employee

def index(request):
    employees = Employee.objects.order_by('id').all()
    context = {'employees': employees}
    return render(request, 'hrmgmt/index.html', context)

دوباره سرور توسعه جنگو ما را در یک نوع مرورگر روشن کنید http://localhost:8000/hr/ وارد فیلد URL و سپس “Enter” را فشار دهید. شما باید خروجی مشابه تصویر زیر را ببینید:

روابط مدل بازگشتی در جنگو

می‌توانید در ستون «مدیر» جدول مشاهده کنید که با موفقیت یک را پیوند داده‌ایم Employee به یک Employee با استفاده از مدل های جنگو

نتیجه

در این مقاله به بررسی موارد استفاده برای اینکه چرا یک رابطه بازگشتی را در یک مدل جنگو پیاده سازی می کنیم، پرداخته ایم. ما از طریق کد تعریف چنین رابطه بازگشتی و همچنین روش تعامل با مدل ها برای حفظ آنها در پایگاه داده و سپس روش بازیابی آنها قدم زدیم. در نهایت، با مشاهده روش نمایش اطلاعات در مدل‌های پشتیبان‌شده پایگاه داده در قالب جنگو، همه چیز را جمع‌بندی کردیم.

اگر تا اینجا پیش رفته اید، می خواهم از شما برای خواندن مقاله من تشکر کنم. امیدوارم این مقاله به شما انگیزه دهد که توسعه وب را با چارچوب وب جنگو بیشتر بررسی کنید. مثل همیشه از هر نظر، پیشنهاد یا انتقادی دعوت می کنم.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-29 21:43:12

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید