از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
روابط مدل بازگشتی در جنگو
سرفصلهای مطلب
نیاز به روابط بازگشتی
بارها در توسعه برنامه های کاربردی وب مدرن وجود دارد که در آن الزامات تجاری ذاتاً روابطی را توصیف می کنند که بازگشتی. یکی از نمونه های شناخته شده چنین قانون تجاری در توصیف کارمندان و رابطه آنها با مدیرانشان است که آنها نیز کارمند هستند. به ماهیت دایره ای آن بیانیه توجه کنید. این دقیقاً همان چیزی است که از یک رابطه بازگشتی استفاده می شود. در این مقاله ما یک نسخه آزمایشی استخوان خالی در جنگو از یک برنامه فهرست کارمندان منابع انسانی (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