مدلهای پایگاه داده در پایتون و جنگو
پایگاه داده در جنگو و پایتون
قبل از شروع کار با پایگاه داده در جنگو باید با مبحث مدل پایگاه داده در جنگو آشنا شویم و مفهوم و عملکرد مدل در پایگاه داده را مورد بررسی قرار دهیم. ازآنجاییکه برنامههای وب مدرن معمولاً از یک ذخیره داده back-end برای مدیریت و دستکاری دادهها استفاده میکنند، منطقی است که جنگو (Django) مکانیسمی را برای مدیریت خودکار دادهها در داخل پایگاه داده در اختیار داشته باشد. جنگو این کار را با ارائه ORM یا بهعبارتدیگر Object-Relational-Mapper انجام میدهد. مدل پایگاه داده در جنگو ابزاری است که برای توصیف نحوه نمایش دادهها در پایگاه داده استفاده میشود. روابط بین مدلها مشابه روابط بین جداول در یک پایگاه داده است.
پیکربندی جنگو برای دسترسی به پایگاه داده
برای اینکه جنگو بتواند دادهها را در پایگاه داده مدیریت کند، ابتدا باید پارامترهای دسترسی به پایگاه داده را پیکربندی کنیم.
این پارامترها در پرونده settings.py برای پروژه شما در دسترس هستند و در جدول زیر توضیح داده شدهاند:
پارامتر | شرح |
DATABASE_ENGINE | موتور پایگاه دادهای که جنگو از آن استفاده خواهد کرد. مقادیر معتبر همه
با حروف کوچک: Postgresql : PostgreSQL که از psycopg استفاده میکند postgresql_psycopg2 : PostgreSQL که از psycopg2 استفاده میکند mysql – MySQL sqlite3 – Sqlite oracle : Oracle مطمئن شوید که قبل از تلاش برای استفاده، حتماً درایور برای پایگاه دادهای که میخواهید استفاده کنید نصب شده است! |
DATABASE_NAME | نام پایگاه داده (یا، در مورد SQLite ، مسیر فایل پایگاه داده) |
DATABASE_USER | نام کاربری برای استفاده در هنگام اتصال به پایگاه داده. |
DATABASE_PASSWORD | رمز عبور استفاده شده هنگام اتصال به پایگاه داده. |
DATABASE_HOST | نام میزبانی که به آن میتوان به پایگاه داده دسترسی پیدا کرد. |
DATABASE_PORT | شماره پورت مورداستفاده برای اتصال به پایگاه داده. |
هنگامیکه پارامترهای خود را تنظیم کردید، میتوانید با استفاده از دستورات زیرخط فرمان (از داخل فهرست پروژه خود) ، در دسترس بودن پایگاه داده خود را آزمایش کنید:
python manage.py shell
from django.db import connection
cursor=connection.cursor()
تعریف مدل پایگاه داده در جنگو
اگر به فایل model.py که در یک برنامه جدید است نگاه کنید، متوجه خواهید شد که این پرونده (به طور پیشفرض) حاوی خطی از جمله:
from django.db import models
جنگو برای نشاندادن هر مدل از زیر کلاس django.db.models.Model استفاده میکند. برای ایجاد یک مدل جدید (آنالوگ جدول در پایگاه داده) ، باید یک کلاس ایجاد کنیم که از django.db.models.Model ارثبری کند.
- کلاس شامل تعدادی ویژگی کلاس است و هر ویژگی معمولاً با ستونی در جدول مطابقت دارد.
- هر نام ویژگی با نام ستون جدول مطابقت دارد.
- هر نوع ویژگی با نوع ستون پایگاه داده مطابقت دارد. همچنین ممکن است هر نوع فیلد مدل دارای یک یا چند پارامتر نامگذاری شده باشد که نشانگر محدودیتها یا سایر الزامات مربوط به این قسمت است.
- جنگو (به طور پیشفرض) به طور خودکار ستون “id” را بهعنوان کلید اصلی به هر جدول اضافه میکند (مگر اینکه یک کلید اصلی برای جدول تعریف کنید).
نکته: اگر جنگو خود را بررسی کنید، یک بخش “Model fields” را مشاهده خواهید کرد که هر یک ازmodel field ها را توصیف میکند. این فیلدها با اجرای توابع مرتبط با فیلد و به دنبال آن پارامترهای اختیاری ایجاد میشوند.
درک Model fields & Options
Model fields جنگو به چند دسته تقسیم میشوند:
- Model fields که نوع دادهای را مشخص میکند.
- Model fields که یک مدل رابطهای را مشخص میکند.
- اینها (بهطورکلی) فیلدهای مدل هستند که یک فیلد را در این مدل مشخص میکنند بهطوریکه به یک فیلد در مدل دیگر ارجاع میدهند.
- این موارد عبارتاند از: ForeignKey – ManyToManyFiled – OneToOneFiled – GenericForeignKey
GenericForeignKey برای پیادهسازی انواع خاصی از روابط که زمینهها را در یک مدل برنامه به مدل دیگری گره میزند (و انجام طیف وسیعی از کارهای غیراستاندارد مدل دیگر) استفاده میشود.
هر model field نیز با استفاده از مجموعه model field options تاحدی قابل تنظیم است.
گزینههای مختلفی وجود دارد که در همه model field ها مشترک است و سایر موارد خاص انواع خاص هستند، گزینه های معمول عبارتند از:
نام گزینه | شرح |
null | پیش فرضها روی False ، اگر روی True تنظیم شوند، نشان میدهد که فیلد ممکن است پوچ باشد. |
blank | در صورت درست بودن، زمینه مجاز است خالی باشد. پیشفرض false میشود. |
db_column | نام ستون پایگاه داده برای استفاده در این قسمت. اگر این قسمت داده نشود، جنگو از نام فیلد استفاده میکند. |
db_index | اگر درست باشد، این یک قسمت نمایه شده خواهد بود. مقدار پیشفرض false میشود |
primary_key | اگر درست باشد، این قسمت کلید اصلی مدل است. |
unique | اگر درست باشد، این قسمت باید در کل جدول منحصربهفرد باشد. |
قرارداد نامگذاری جدول در جنگو
هنگامیکه مدلی به جدول تبدیل میشود، جنگو همیشه از یک قرارداد نامگذاری خاص استفاده میکند (مگر اینکه آن را نادیده بگیرید).
Django همیشه از app_classname برای نام جدول استفاده میکند، جایی که classname نام کلاسی است که شما تعیین کردهاید. حروف همیشه به حروف کوچک نگارش میشوند، بنابراین نام جدولها با حروف کوچک است. هنگام استفاده از Relational Model Fields بهعنوانمثال، ManyToManyField ، جنگو نام فیلد را به انتهای جدول اضافه میکند تا یک جدول جدید ایجاد کند که حاوی رابطه مشخص شده در مدل باشد.
نحوه ایجاد مدل پایگاه داده در جنگو
فرض کنید شما در حال ایجاد یک وبسایت هستید که شامل یک سیستم ثبتنام برای رویدادها باشد.
در چنین حالتی، شما احتمالاً به چند جدول نیاز دارید:
- جدولی شامل رویدادها، با نام رویدادها، تاریخ شروع، تاریخ پایان، زمان شروع، زمان پایان، قیمتها، ارز و شرح رویداد.
- جدولی شامل افراد ثبتنامشده، با آدرس ایمیل، نام، تلفن
- جدولی شامل ثبتنام رویدادها که افراد ثبتنامشده را با رویدادها مرتبط میکند.
این جدول با استفاده از یک رابطه بسیار زیاد اجرا خواهد شد، بنابراین مدل آن را بهتنهایی ایجاد میکند.
کد نمونه برای پیادهسازی این مدل بهصورت زیر است:
from django.db import models
class Events(models.Model):
name = models.CharField(max_length=128,
help_text='Name of Event')
start_date = models.DateField(help_text='Start date of Event')
end_date = models.DateField(help_text='End date of Event')
start_time = models.TimeField(help_text='Start time of Event')
end_time = models.TimeField(help_text='End Time of Event')
description = models.TextField(help_text='Description of Event')
class People(models.Model):
fname = models.CharField(max_length=64, help_text='First Name')
lname = models.CharField(max_length=64, help_text='Last Name')
email = models.EmailField(max_length=128, help_text='Email Address')
phone = models.CharField(max_length=16, help_text='Phone Number')
enrollments= models.ManyToManyField(Events)
پس از تبدیلشدن به یک ساختار پایگاه داده در جنگو، این کد SQL است که تولید میشود:
BEGIN;
CREATE TABLE "demoapp_events" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(128) NOT NULL,
"start_date" date NOT NULL,
"end_date" date NOT NULL,
"start_time" time NOT NULL,
"end_time" time NOT NULL,
"description" text NOT NULL
)
;
CREATE TABLE "demoapp_people" (
"id" integer NOT NULL PRIMARY KEY,
"fname" varchar(64) NOT NULL,
"lname" varchar(64) NOT NULL,
"email" varchar(128) NOT NULL,
"phone" varchar(16) NOT NULL
)
;
CREATE TABLE "demoapp_people_enrollments" (
"id" integer NOT NULL PRIMARY KEY,
"people_id" integer NOT NULL REFERENCES "demoapp_people" ("id"),
"events_id" integer NOT NULL REFERENCES "demoapp_events" ("id"),
UNIQUE ("people_id", "events_id")
)
;
COMMIT;
توجه داشته باشید که چگونه جنگو به طور خودکار جدول اضافی را برای پیادهسازی رابطههای بسیار زیاد ایجاد میکند.
اعتبارسنجی مدل در جنگو
با استفاده از دستور “اعتبارسنجی” با manage.py میتوانید مدلهای خود را تأیید کنید تا از نحو و بستههای صحیح استفاده کنند.
این دستور تمام مدلهای پروژه را تأیید میکند، نه فقط یک برنامه واحد. در نتیجه، معمولاً افزودن یک برنامه و تأیید اعتبار آن، برعکس اضافهکردن و تأیید اعتبار یکباره برنامه، توصیه میشود.
خطاها را اصلاح کنید و اعتبار را ادامه دهید تا زمانی که دستور 0 خطا را برگرداند.
python manage.py validate
تولید و اجرای SQL
پس از ایجاد برنامه، میتوانید SQL را که مدل شما تولید میکند مورد بررسی قرار دهید.
دستور ایجاد کد SQL برای بررسی sqlall است. یکبار دیگر، از دستور mange.py sqlall و به دنبال آن نام برنامه برای تولید کد SQL برای بررسی استفاده کنید.
هنگامیکه آماده ایجاد جداول در خود پایگاه داده هستید، میتوانید دستور زیر را صادر کنید:
python manage.py syncdb
این دستور به پایگاه داده متصل میشود و جداول برای تمام برنامههایی که به این پروژه متصل هستند ایجاد میکند. اگر جدولی از قبل وجود داشته باشد، Django تأیید میکند که حداقل شامل ستونهای تعریف شده با برنامه است. اگر جدول دارای ستونهای اضافی باشد (یا جداول اضافی در پایگاه داده وجود داشته باشد) ، جنگو خطایی را برنمیگرداند. اما اگر جدول فاقد ستون یا نوع موردنیاز باشد، جنگو خطا برمیگرداند.
python manage.py sqlall demoapp
افزودن داده به مدل در جنگو
هنگامیکه مدل را ایجاد کردید، افزودن داده به آن نسبتاً آسان است: ابتدا یک شی جدید برای مدلی که میخواهید به آن داده اضافه کنید ایجاد کنید.
سازنده باید تمام دادههای زمینه موردنیاز را در name/value pairs منتقل کند.
پس از ایجادشی، میتوانید آن را با استفاده از روش .save() در پایگاه داده ذخیره کنید. این تکنیک برای همه مدلها جواب میدهد، افزودن دادهها صرفاً ایجادشی برای مدل و صرفهجویی در آن است.
from demoapp.models import Events
from datetime import date
event = Events(name='Introduction to Python',
start_date=date(2007,01,01),
end_date=date(2007,01,04),
start_time='09:00:00',
end_time='17:00:00',
description='This is a Python training event')
event.save()
بازیابی اطلاعات ساده با استفاده از یک مدل
اکنونکه میدانیم چگونه دادهها را در مدل قرار دهیم و آنها را بهروز کنیم، بیایید کمی در مورد بازیابی دادهها از یک مدل صحبت کنیم.
چند روش مختلف وجود دارد که ما میتوانیم برای بازیابی دادهها از یک مدل ساده مانند نمونهای که قبلاً ایجاد کردهایم، استفاده کنیم:
برای بازیابی تمام سطرها از یک جدول خاص، میتوانید از روش all () استفاده کنید. متد all () مانند بیشتر متدهای برگشت داده QuerySet را برمیگرداند. اگر تکرار شود، QuerySet نمونههایی از شی model را برمیگرداند و هر نمونه شامل دادههای آن رکورد است. برای بهروزرسانی پایگاه داده، هر شی ممکن است اصلاح و ذخیره شود.
نکته:
هر مدل در جنگو با یک Manager مرتبط است (مدیر با ویژگی .object مدل ارجاع میشود). Manager یک رابط است که از طریق آن عملیات query بر روی مدلهای جنگو انجام میشود. Manager خود مجموعهای از روشها را برای ارتباط با پایگاه داده در اختیار ما قرار میدهد.
data = Events.objects.all()
for e in data:
print e.name, 'starts on', e.start_date
حذف رکوردها در جنگو
از روش .delete() شما برای حذف سوابق از مدل داده استفاده میشود. این متد نیز ممکن است در QuerySet اجرا شود تا تمام رکوردهایی که QuerySet ارجاع میدهد حذف شود.
حذف تمام سوابق از مدل Event
data = Events.objects.all()
for e in data:
e.delete()
حذف تمام سوابق از مدل Event
data = Events.objects.all().delete()
حذف همه رویدادهای گذشته از مدل Event
data = Events.objects.all()
data = data.filter(start_date__lte=date.today())
data.delete()
فعالکردن اینترفیس مدیریتاستفاده از رابط مدیریت Django (اینترفیس مدیریت جنگو)
رابط یا اینترفیس مدیریت بهگونهای طراحی شده است که روشی آسان برای مدیریت و دستکاری دادههای ذخیره شده در مدل ارائه میدهد. برای اینکه یک مدل خاص در رابط مدیر ظاهر شود، ابتدا باید admin.py را در برنامه خود ایجاد کنید.
فایل admin.py شامل نمایش مدلهای شما در رابط مدیر (ModelAdmin) است.
from django.contrib import admin
from demo.demoapp.models import *
class EventsAdmin(admin.ModelAdmin):
list_display=('name','start_date')
admin.site.register(Events, EventsAdmin)
class PeopleAdmin(admin.ModelAdmin):
list_display=('lname','fname')
admin.site.register(People, PeopleAdmin)
برای نمایش آن، باید آن را در قسمت Admin سایت ثبت کنید. هنگامیکه مدلهای خود را بهروز کردید، برای اطمینان از همگامسازی مدل با طرح پایگاه داده، syncdb را انجام دهید. برای فعالکردن رابط مدیر، باید یک URL برای آن به urls.py اضافه کنید:
admin.py: این فایل شامل نمایشی از مدلهای People و Events در رابط مدیر است. وقتی این مورد اضافه شد، این اشیا در آن رابط ظاهر میشوند.
from django.contrib import admin
admin.autodiscover()
urlpatterns += patterns ('',(r'^admin/', include(admin.site.urls)))
همچنین باید django.contrib.admin را در settings.py به INSTALLED_APPS اضافه کنید.
سرانجام، syncdb را اجرا کنید تا اجزای مدیر موردنیاز ایجاد شود. در آخر، ModelAdmin دارای تعدادی ویژگی است که ممکن است برای کنترل نحوه نمایش سایت مدیر تنظیم شود.
بهعنوانمثال، تنظیم ویژگی list_display به ما امکان میدهد ستونهای نمایشدادهشده در صفحه لیست تغییر مدیر را لیست کنیم.