النماذج Models والاستعلام عن البيانات في Django: أساس البرمجة الموجهة للكائنات في تطبيقات الويب
تُعد بيئة Django من أكثر الأطر شيوعًا في تطوير تطبيقات الويب باستخدام لغة البرمجة Python، وذلك لما تتميز به من بساطة في البنية، وقوة في الإمكانيات، واعتمادها الكامل على فلسفة “عدم تكرار نفسك” (Don’t Repeat Yourself – DRY). ومن أهم اللبنات الأساسية في Django، نجد “النماذج” (Models)، والتي تمثل العمود الفقري للطبقة الخاصة بالتعامل مع قواعد البيانات. فهي الطبقة التي تجسد منطق البيانات، وتعكس الكيانات الحقيقية في قاعدة البيانات، وتوفّر واجهات برمجية للاستعلام عنها وتعديلها.
يهدف هذا المقال إلى تقديم شرح موسع وعميق حول النماذج في Django، بالإضافة إلى آلية تنفيذ الاستعلامات على قاعدة البيانات من خلال واجهات ORM (Object-Relational Mapping) التي يوفرها الإطار. ويستعرض المقال الجوانب النظرية والتطبيقية المتعلقة بالنماذج، مرفقًا بالأمثلة العملية، وأفضل الممارسات المتبعة في تصميم النماذج وتنفيذ الاستعلامات المعقدة.
1. تعريف النماذج في Django وأهميتها
في بنية MVC، يُعتبر النموذج (Model) مسؤولًا عن تمثيل البيانات والتعامل معها. في Django، يتم تعريف النماذج باستخدام الأصناف (Classes) بلغة Python، والتي تُشتق من الصنف الأساسي django.db.models.Model.
كل نموذج يمثّل جدولًا في قاعدة البيانات، وكل خاصية داخل النموذج تُترجم إلى عمود داخل الجدول. Django تتولى تلقائيًا عملية تحويل الأصناف إلى جداول، وتوفر واجهة برمجية عالية المستوى للتعامل مع هذه البيانات دون الحاجة إلى كتابة استعلامات SQL مباشرة.
2. إنشاء نموذج بسيط في Django
يتم إنشاء النماذج داخل ملف models.py في كل تطبيق فرعي داخل مشروع Django. كمثال، يمكن إنشاء نموذج يمثل “مقالًا” داخل موقع إلكتروني على النحو التالي:
pythonfrom django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published_date = models.DateTimeField(auto_now_add=True)
author = models.CharField(max_length=100)
def __str__(self):
return self.title
شرح الخصائص:
-
CharField: حقل يستخدم لسلاسل قصيرة. -
TextField: حقل يستخدم للنصوص الطويلة. -
DateTimeField: حقل لتخزين التاريخ والوقت. -
__str__: دالة ترجع تمثيل نصي للنموذج عند عرضه.
بعد تعريف النموذج، يجب تنفيذ الأمر التالي لإنشاء الهجرة (Migration) الخاصة به:
bashpython manage.py makemigrations python manage.py migrate
3. أنواع الحقول المستخدمة في النماذج
يوفر Django مجموعة واسعة من الحقول التي يمكن استخدامها في النماذج، مثل:
| نوع الحقل | الاستخدام |
|---|---|
CharField |
سلاسل نصية قصيرة |
TextField |
نصوص طويلة |
IntegerField |
أرقام صحيحة |
FloatField |
أرقام عشرية |
BooleanField |
قيم منطقية (True/False) |
DateField و DateTimeField |
التواريخ والأوقات |
EmailField |
عناوين البريد الإلكتروني |
URLField |
روابط URL |
FileField و ImageField |
تحميل ملفات أو صور |
ForeignKey |
علاقة واحد إلى متعدد |
ManyToManyField |
علاقة متعدد إلى متعدد |
OneToOneField |
علاقة واحد إلى واحد |
4. العلاقات بين النماذج
تعتمد Django على أنواع الحقول الخاصة لتحديد العلاقات بين الجداول، مثل:
علاقة واحد إلى متعدد:
pythonclass Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
علاقة متعدد إلى متعدد:
pythonclass Student(models.Model):
name = models.CharField(max_length=100)
class Course(models.Model):
name = models.CharField(max_length=100)
students = models.ManyToManyField(Student)
5. الاستعلام عن البيانات باستخدام ORM
يوفر Django واجهة برمجية قوية لإنشاء استعلامات على قاعدة البيانات باستخدام الكائنات بدلًا من كتابة SQL مباشر. تشمل أهم العمليات:
5.1 إنشاء كائن جديد:
pythonarticle = Article(title='مقال جديد', content='هذا نص المقال', author='محمد')
article.save()
5.2 استرجاع البيانات:
pythonall_articles = Article.objects.all()
one_article = Article.objects.get(id=1)
5.3 التصفية (Filter):
pythonfiltered_articles = Article.objects.filter(author='محمد')
5.4 الترتيب:
pythonordered_articles = Article.objects.order_by('-published_date')
5.5 التحديد المتقدم باستخدام Q:
pythonfrom django.db.models import Q
Article.objects.filter(Q(author='أحمد') | Q(title__contains='مقدمة'))
6. تحديث البيانات
يمكن تحديث بيانات كائن معين كما يلي:
pythonarticle = Article.objects.get(id=1)
article.title = 'عنوان جديد'
article.save()
كما يمكن التحديث دفعة واحدة:
pythonArticle.objects.filter(author='محمد').update(author='أحمد')
7. حذف البيانات
يمكن حذف سجل معين باستخدام:
pythonarticle = Article.objects.get(id=1)
article.delete()
أو الحذف الجماعي:
pythonArticle.objects.filter(author='أحمد').delete()
8. الدوال الإضافية في ORM
يوفر Django مجموعة من الدوال الجاهزة للاستعلامات المتقدمة:
-
count(): لعد النتائج. -
exists(): للتحقق من وجود نتائج. -
distinct(): لجلب القيم الفريدة. -
values()وvalues_list(): للحصول على تمثيلات خاصة للبيانات. -
annotate()وaggregate(): لتنفيذ العمليات الحسابية مثل المجموع والمتوسط.
9. استخدام Prefetch و Select Related لتحسين الأداء
عند التعامل مع العلاقات، قد تُسبب الاستعلامات المتعددة في تحميل زائد على قاعدة البيانات. لذلك يوفر Django تقنيات لتحسين الأداء:
select_related:
يُستخدم لعلاقات واحد إلى واحد أو واحد إلى متعدد:
pythonbooks = Book.objects.select_related('author').all()
prefetch_related:
يُستخدم لعلاقات متعدد إلى متعدد:
pythoncourses = Course.objects.prefetch_related('students').all()
10. النماذج المجردة (Abstract Models)
تُستخدم لإنشاء نماذج قابلة لإعادة الاستخدام، دون أن تنشئ جداول فعلية في قاعدة البيانات:
pythonclass TimeStampedModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Article(TimeStampedModel):
title = models.CharField(max_length=200)
11. إدارة النماذج (Model Managers)
يمكنك تخصيص الطريقة التي تُسترجع بها البيانات عبر إنشاء “مدير” مخصص:
pythonclass PublishedManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(published=True)
class Article(models.Model):
title = models.CharField(max_length=200)
published = models.BooleanField(default=False)
objects = models.Manager() # المدير الافتراضي
published_objects = PublishedManager() # مدير مخصص
12. النماذج وتكاملها مع لوحة التحكم (Django Admin)
بمجرد إنشاء النموذج وتسجيله في admin.py، يمكن إدارة بياناته من واجهة Django Admin:
pythonfrom django.contrib import admin
from .models import Article
admin.site.register(Article)
13. الممارسات الفضلى عند التعامل مع النماذج
-
استخدام أسماء وصفية للحقول.
-
تحديد قيود مثل
unique=Trueوnull=Falseللحفاظ على سلامة البيانات. -
استخدام العلاقات المناسبة بدلًا من تكرار البيانات.
-
فصل المنطق المعقد في طبقات مخصصة مثل
Model ManagersأوQuerySetمخصص. -
الاستفادة من
index_togetherوunique_togetherلأداء أفضل. -
اعتماد الفهارس
db_index=Trueللحقول التي تُستخدم في التصفية.
14. جدول يوضح الفرق بين بعض أوامر ORM
| الأمر | الاستخدام | النتيجة |
|---|---|---|
all() |
جلب جميع السجلات | QuerySet بكل الكائنات |
get() |
جلب كائن واحد بشرط دقيق | كائن مفرد أو خطأ |
filter() |
تصفية السجلات | QuerySet جزئي |
exclude() |
استثناء سجلات معينة | QuerySet |
order_by() |
ترتيب النتائج | QuerySet مرتب |
values() |
عرض البيانات كقائمة قواميس | قائمة Dict |
annotate() |
عمليات رياضية | QuerySet مضاف له الحقول الحسابية |

