آموزش جنگو (Basic) : جلسه چهار | کار کردن با دیتابیس

در این جلسه با هم نحوه کار با دیتابیس در جنگو را بررسی خواهیم کرد . با ما همراه باشید .آموزش جنگو : جلسه چهار | کار کردن با دیتابیسساخت یک مدل و جدول (TABLE)برای ساخت یک جدول در دیتابیس جنگو , ابتدا وارد فایل models.py در اپ مربوطه بشوید . در اینجا کلاسی با نامی دلخواه ایجاد کنید . در واقع هر کلاس یک جدول است و نام هر کلاس نیز نام جدول مربوطه در دیتابیس شماست . شما میتوانید تعداد کلاس های زیادی با نام های مختلف را ایجاد کنید . ولی مهم این است که همه کلاس ها باید از models.Model ارث بری کنند .برای مثال در کد زیر دو جدول با نام های question و choice ایجاد خواهیم کرد . این دو جدول در واقع دو کلاس با نام های مشابه هستند و نکته مهم این است که هردو از models.Model ارث بری میکنند .from django.db import models class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)فیلد یا FIELDهر ویژگی یا به اصطلاح هر ستون یک فیلد را به خود اختصاص می دهد . برای مثال به یک وبسایت فروش مواد غذایی دقت کنید . این وبسایت یک جدول (TABLE) برای لیست مواد غذایی خود را دارد . حال هر جدول تعدادی ستون در خود دارد که هر یک از این ستون ها برای یک ویژگی از یک شی است . برای مثال یک کیک را در نظر بگیرید که ویژگی هایی مانند وزن , قیمت ,طعم و غیره را دارد . هر یک از این ویژگی ها درون یک فیلد تعیین میشوند .فیلد ها در جنگو در واقع متغییر ها و ویژگی هایی هستند که درون یک کلاس ایجاد میشوند . آنها انواع مختلفی نیز دارند . برای مثال str , int , ip , email , password و غیره از انواع فیلد ها در جنگو هستند که در ادامه به بررسی چندی از آنها خواهیم پرداخت . در جلسات بعدی به طور کامل انواع فیلد ها در جنگو را بررسی خواهیم کرد .from django.db import models class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)هر کدام از متغییر های بالا در واقع یک فیلد را در یک جدول خاص تشکیل میدهند . برای مثال در جدول Qusetion دو فیلد قرار داده شده است . هر کدام از فیلد ها اسمی را به خود اختصاص داده اند که همان اسم متغییر آنهاست . برای مثال در این تیبل question text و pub date فیلد های ما هستند . همانطور که میبینید با استفاده از models و فراخوانی یکی از کلاس های درون این فایل به این فیلد ها نوع خاصی اختصاص داده شده است . این یعنی آنها فقط می توانند نوع های خاصی از داده را بپذیرند .برای مثال به فیلد های جدول Qusetion دو نوع charfield و datetimefield اختصاص داده شده است . به متغییر Question text که قرار است متن سوال ما را ذخیره کند نوع CharField و به متغییر یا فیلد pub date که دربردارنده تاریخ ارسال سوال است نوع datetimefield داده شده است . در لیست زیر بعضی از انواع فیلد ها را بررسی می کنیم :نوع CharField : این نوع از فیلد برای نوع های داده ای str است . برای مثال پسوورد ها , نام ها ,یوزرنیم ها و غیره از این نوع داده ای استفاده میکنند ; چرا که آنها رشته ای از اعداد ,حروف و یا سمبل ها می باشند .نوع DateTimeField : این نوع از فیلد برای تاریخ و زمان استفاده میشود . هنگامی که شما نیاز دارید تا یک تاریخ خاص را در دیتابیس ثبت کنید میتوانید از این نوع فیلد استفاده کنید . برای مثال تاریخ ثبت نام یک کاربر و یا تاریخ ایجاد یک مقاله و یا تاریخ خرید اشتراک ویژه و یا ...نوع IntegerField : این نوع از فیلد برای نوع های داده ای عددی به کار میرود . البته نوع های عددی دیگری نیز وجود دارند که در قسمت های بعدی مورد بررسی قرار میگیرند . تفاوت آن با CharField در این است که در این نوع داده ای میتوان عملیات های ریاضی را اعمال کرد . برای مثال برای تعداد محصولات یک فروشگاه باید integerField استفاده کرد زیرا ممکن است تعداد محصولات پس از خرید محصول تغییر کنند و کم یا زیاد شوند.فیلد های خاصبرای بررسی این مفهوم , ابتدا به دو مدل (همان جدول) زیر نگاه کنید .from django.db import models class manager(models.Model): name = models.CharField(max_length=200) point = models.IntegerField(default=0) class color(models.Model): color_name = models.CharField(max_length=200) class car(models.Model): name = models.CharField(max_length=200) class factory(models.Model): name = models.CharField(max_length=200) manager = models.IntegerField(default=0)در کد بالا ما سه مدل با نام های manager , car , color , factory داریم . هر کدام از آنها دارای رکورد هایی در جدول های خود هستند . حال فرض کنید که شما نیاز دارید که در یک فیلد از یک جدول , رکورد یا شی ای از جدول دیگری را به عنوان مقدار ذخیره کنید . در ادامه بهتر متوجه خواهید شد که منظور ما چیست !ما سه نوع رابطه داریم که مدل ها را میتواند به یکدیگر ارتباط دهد , شما می توانید از آنها به شکل فیلد استفاده کنید . بنابراین سه نوع فیلد خواهیم داشت :فیلد OneToOneField : رابطه های یک به یک را می سازند . برای مثال هر کارخانه که در این کد یک شی از مدل factory است . هر کارخانه یک مدیر دارد که هر مدیر و اطلاعات مخصوص به او در مدل manager ثبت می شود (یعنی هر شی از مدل manager یک مدیر است) . حال فرض کنید شما 4 مدیر در داخل مدل manager ثبت کرده اید و اکنون میخواهید در یک کارخانه در مدل factory یک مدیر را انتخاب کنید (می خواهید بگویید صاحب این کارخانه چه کسی است) . طبیعی است که باید به یکی از اشیای مدل manager اشاره کنید . در این صورت باید فیلد OneToOneField را در مدل factory ایجاد کنید و سپس یکی از شی های مدل manager را به عنوان مقدار به آن ارسال کنید . به یاد داشته باشید هر کارخانه یک مدیر دارد و هر مدیر فقط یک کارخانه را دارد .نکته : روابط یک به یک یا one to one یا فیلد OneToOneField یعنیهر مدل یک شی از مدل های دیگر را میتواند انتخاب کند و هر شی از مدل های دیگر میتواند به یک مدل ارتباط پیدا کند .فیلد ForeingKey : رابطه های یک به چند هستند . برای مثال هر کارخانه که در این کد مدل factory است چند مدل ماشین دارد که هر ماشین اطلاعات مخصوص به خود را در مدل car دارد (هر شی در مدل car یک ماشین است) . حال فرض کنید شما 2 مدل ماشین مختلف را در داخل مدل car ثبت کرده اید و اکنون میخواهید در مدل factory چند مدل ماشین را ذخیره کنید یا به اصطلاح چند رکورد یا همان شی را از مدلی دیگر انتخاب کنید . باید فیلد ForeingKey در مدل factory ایجاد کرده و سپس چند شی از مدل car را در این فیلد انتخاب کنید . به یاد داشته باشید در اینجا که هر کارخانه چند نوع ماشین دارد ولی هر نوع ماشین مربوط به یک کارخانه است .نکته : روابط یک به چند یا foreingkey یا فیلد ForeingKey یعنیهر مدل چند شی از مدلی دیگر را میتواند انتخاب کند ولی هر شی از مدل های دیگر میتواند فقط به یک مدل ارتباط پیدا کند .فیلد ManyToManyField : رابطه های چند به چند هستند . برای مثال هر کارخانه چندین رنگ از ماشین ها را تولید میکند . در اینجا مدل factory چندین رنگ را باید از مدل color بتواند درون خود ذخیره کند . این به این معنی است که هر کارخانه میتواند چندین مدل رنگ را داشته باشد و هر رنگ در مدل color میتواند با چندین کارخانه ارتباط داشته باشد (یعنی هر رنگ را چند کارخانه تولید کنند) . در اینجا باید یکی از فیلد های مدل factory را فیلد ManyToManyField قرار داده و سپس چندین شی از مدل color انتخاب کنیم .نکته : روابط چند به چند یا Many to Many یا فیلد ManyToManyField یعنیهر مدل چند شی از مدلی دیگر را میتواند انتخاب کند و هر شی از مدل دیگر میتواند به چند مدل ارتباط پیدا کند .بسیار خب , اگر تا اینجا چیزی از این نوع فیلد ها متوجه نشدید نگران نباشید . فهمیدن این بخش کمی مشکل است . در پروژه بعدی بیشتر با این نوع از فیلد ها اشنا خواهید شد .فعالسازی مدل ها و appساختار جنگو به نحوی طراحی شده است گه بتواند فعالیت های خود را در چند app جدا کند و آنها را انجام دهد . پس یک app میتوانند یکبار نوشته شوند و در پروژه های مختلف دوباره استفاده شوند . بیایید به ادامه پروژه قبلی خود بپردازیم .حال شما app جدیدی با نام polls ایجاد کرده اید . این به این معنی میتواند باشد که آن را نوشته اید یا از کدی دیگر کپی کرده اید . به هر حال باید به جنگو به نحوی بفهمانید که این یک app جدید است و باید در برنامه نصب شود . برای اینکار به فایل mysite/settings.py بروید و متغییر INSTALLED_APPS را بصورت زیر تغییر دهید .INSTALLED_APPS = [ 'polls.apps.PollsConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ‘polls‘, ]اکنون شما app جدیدی که نوشتید را به جنگو معرفی کردید و جنگو اکنون از آن استفاده خواهد کرد . حال بیایید دستور دیگری را در ترمینال وارد کنیم .به دایرکتوری و مسیر پروژه بروید و دستور زیر را در جایی که فایل manage.py وجود دارد اجرا کنید .python manage.py makemigrations pollsحال شما باید نتیجه را بصورت زیر ببینید :Migrations for 'polls': polls/migrations/0001_initial.py -Create model Question - Create model Choiceبا اجرای این دستور به جنگو میگویید که شما تغییراتی در مدل های خود اعمال کردید و می خواهید تغییرات در یک فایل migration ذخیره شوند. (در اینجا تغییرات ساختن مدل های جدید بود)فایل های migration در واقع فایل هایی در هارد شما هستند که میگویند جنگو چطور تغییرات را در مدل های شما اعمال کرده است . اگر دوست دارید میتوانید نگاهی به آنها بیاندازید . این فایل در مسیر polls/migrations/ ساخته میشوند . گرچه ,لازم نیست پس از هر بار اعمال دستور makemigrations نگاهی به این فایل ها بیندازید . این فایل ها در جهت این ساخته میشوند تا بتوانید راحت تر درک کنید که جنگو چطور تغییرات را در دیتابیس ایجاد کرده است .حال کافی است بعد از اجرای دستور بالا دستور migrate را برای اعمال فایل های migration در داخل دیتابیس اجرا کنید . به صورت زیر دستور را میتوانید اجرا کنید .python manage.py migrateحال شما باید نتیجه را بصورت زیر ببینید :Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Rendering model states... DONE Applying polls.0001_initial... OKاین دستور تمام فایل های migration که اعمال نشده اند را پیدا میکند و سپس آنها را در دیتابیس اعمال میکند. این به معنی است که جنگو میداند که کدام فایل های migration هنوز در دیتابیس اعمال نشده اند . جنگو این کار را با ذخیره کردن وضعیت اعمال شدن یا نشدن فایل های migration در ستونی از دیتابیس با نام Django_migrations انجام میدهد .دلیل به وجود امدن سیستم migration , به وجود امدن امکان تغییر ستون و جداول دیتابیس بدون از دست دادن اطلاعات است . آنها بسیار قدرتمند هستند و به شما اجازه میدهند تا هر بار دیتابیس را تغییر بدهید , بدون اینکه نیازی به حذف جدول ها یا غیره داشته باشید .پس به یاد داشته باشید اعمال تغییرات بر دیتابیس (ساخت مدل جدید یا تغییر مدل های قبلی یا فیلد های هر مدل) سه مرحله اساسی دارد که پس از هر تغییر باید انجام شود .اعمال تغییر در فایل models.pyاجرای دستور python3 manage.py makemigrations (تغییرات اعمال شده را در فایل migration ذخیره میکند )اجرای دستور python3 manage.py migrate (تغییرات فایل migration را در دیتابیس اعمال میکند )در این مقاله با انواع فیلد ها و نحوه ساخت یک جدول در دیتابیس و فایل های migration آشنا شدید . در قسمت بعدی با ترمینال جنگو (shell) آشنا خواهید شد .