في هذا الدرس سنتعلم كيفية تحميل الصورة باستخدام Django. سنقوم ببناء نسخة من Instagram.
تثبيت الأساسيات
سواء كنت تستخدم جهاز كمبيوتر محمول يعمل بنظام التشغيل Windows أو Mac، يعد سطح المكتب
مكانًا مناسبًا لوضع الأكواد الخاصة بنا. و يعد هذا رأيي الخاص فالموقع لا يهم المهم أن تكون الأكواد متاحة بسهولة.
افتح سطر الأوامر وانتقل إلى سطح المكتب. ثم قم بإنشاء دليل، insta
، لمشروعنا.
سنقوم بإنشاء بيئة افتراضية جديدة، وتفعيلها، وتثبيت كل من Django و Pillow وهي مكتبة بايثون لمعالجة الصور يعتمد عليها Django في التعامل مع ملفات الصور.
# Windows
> cd onedrive\desktop\code
> mkdir insta
> cd insta
> python -m venv .venv
> .venv\Scripts\Activate.ps1
(.venv) > python -m pip install django
(.venv) > python -m pip install pillow
# macOS
% cd ~/desktop/code
% mkdir insta
% cd insta
% python3 -m venv .venv
% source .venv/bin/activate
(.venv) % python3 -m pip install django
(.venv) % python -m pip install pillow
الآن سنقوم بإنشاء مشروع Django جديد والمسمى django_project
وتطبيق جديد يسمى posts
.
(.venv) > django-admin startproject django_project .
(.venv) > python manage.py startapp posts
نظرًا لأننا أضفنا تطبيقًا جديدًا، فنحن بحاجة إلى إخبار Django عنه في ملف settings.py في قسم INSTALLED_APPS
.
# django_project/settings.py
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"posts", # جديد
]
سنقوم الآن بتشغيل python manage.py migrate
لإعداد قاعدة البيانات الجديدة لمشروعنا.
(.venv) > python manage.py migrate
النماذج
يعد البدء بنموذج قاعدة البيانات خيارًا جيدًا. في حالتنا، سيحتوي النموذج الخاص بنا Post
على حقلين فقط: title
cover
.
سنقوم أيضًا بتضمين طريقة __str__
أدناه حتى يظهر title
في مشرف Django لاحقًا.
# posts/models.py
from django.db import models
class Post(models.Model):
title = models.TextField()
cover = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
سيكون موقع image
التي تم تحميلها في MEDIA_ROOT/image
.
في Django، إعدادات MEDIA_ROOT هو المكان الذي نحدد فيه موقع جميع العناصر التي سبقوم المستخدم بتحميلها ويسنعمل على ذلك الأن.
إذا أردنا استخدام ملف عادي، فقد يكون الاختلاف الوحيد هو تغيير ImageField إلى FileField.
MEDIA_ROOT
افتح config/settings.py
في محرر النصوص الخاص بك لإضافة بعض الإعدادات .
افتراضيًا، يكون MEDIA_URL
و MEDIA_ROOT
فارغين ولا يتم عرضهما، لذا نحتاج إلى تهيئتهما:
MEDIA_ROOT
هو المسار لدليل الملفات التي تم تحميلها بواسطة المستخدم.MEDIA_URL
هو عنوان URL الذي يمكننا استخدامه في قوالبنا.
# config/settings.py
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
يمكننا اختيار اسم آخر غير media
هنا ولكن هذا مايوصي به Django. سنقوم أيضًا بإنشاء مجلد images
بداخله لاستخدامه قريبًا.
(.venv) $ mkdir media
(.venv) $ mkdir media/images
Admin
الآن سنقوم بتحديث ملف posts/admin.py
حتى نتمكن من رؤية تطبيق Post
في مسؤول Django.
# posts/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
أما الان ستقوم بإنشاء ملف هجرة جديد.
(.venv) > python manage.py makemigrations
Migrations for 'posts':
posts/migrations/0001_initial.py
- Create model Post
ثم قم بتشغيل migrate
لتحديث قاعدة البيانات.
(.venv) > python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, posts, session
s
Running migrations:
Applying posts.0001_initial... OK
يمكننا الآن إنشاء حساب superuser
للوصول إلى المسؤول ثم تنفيذ runserver
لتشغيل خادم الويب المحلي لأول مرة.
(.venv) > python manage.py createsuperuser
(.venv) > python manage.py runserver
إذا انتقلت إلى http://127.0.0.1:8000/admin فستتمكن من تسجيل الدخول إلى موقع إدارة Django. و يجب أن يعيد توجيهك إلى هذه الصفحة:
انقر على الرابط “+ إضافة” بجوار Posts
. يمكنك إضافة ما تريد ولكن في هذا الدرس سأقوم بنشر منشور حول تميمة Django. و يمكنك تحميلها من هنا إذا أردت.
عند القيام بعملية “حفظ” ستتم إعادة توجيهك إلى صفحة المنشورات حيث يمكننا رؤية جميع منشوراتنا.
إذا نظرت داخل مجلد media
المحلي في مشروعك، فسترى أسفل images
أن هناك الآن ملف الصورة djangopony.png
. يرى! و هذا هو ما سيفعله MEDIA_URL
.
حسنًا، في هذه المرحلة نكون قد انتهينا من الأساسيات. ولكن دعونا نخطو خطوة إلى الأمام ونعرض منشوراتنا بإعداد كل من ملفات urls.py
, views.py
والقوالب.
عناوين URL
الشيء المحير في Django هو أنك غالبًا ما تحتاج إلى 4 ملفات مختلفة ولكن مترابطة لصفحة ويب واحدة: models.py
, urls.py
, views.py
، وملف html
للقالب.
أجد أنه من السهل التفكير في هذا الأمر من خلال الترتيب التالي : النماذج -> عناوين url -> العرض -> ملفات القوالب. وبما أننا إنتهينا من النموذج فهذا يعني أننا سنتوجه لمسارات عناوين URL.
سنحتاج إلى تحديثين لملف urls.py
. الأول في ملف config/urls.py
على مستوى المشروع، نحتاج إلى إضافة عمليات استيراد settings
, include
، static
ثم نحدد مسارًا لتطبيق posts
.
لاحظ أننا نحتاج أيضًا إلى إضافة MEDIA_URL
إذا كانت الإعدادات في وضع DEBUG
، وإلا فلن نتمكن من عرض الصور التي تم تحميلها محليًا.
# config/urls.py
from django.contrib import admin
from django.conf import settings # جديد
from django.urls import path, include # جديد
from django.conf.urls.static import static # جديد
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("posts.urls")), # جديد
]
if settings.DEBUG: # جديد
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
بعد ذلك، سنحتاج إلى فرز مسارات URL داخل تطبيق post
. قم أولاً بإنشاء هذا الملف الجديد في محرر النصوص الخاص بك posts/urls.py
. بعد ذلك، سنضع جميع المشاركات على الصفحة الرئيسية، لذا استخدم السلسلة الفارغة “” كمسار طريقنا مرة أخرى.
# posts/urls.py
from django.urls import path
from .views import HomePageView
urlpatterns = [
path("", HomePageView.as_view(), name="home"),
]
يشير هذا إلى عرض يسمى HomePageView
والتي سنقوم بإنشائه الأن.
العروض
يمكننا استخدام ListView
العرض القائم على الفئة، واستيراد نموذج Post
، ثم إنشاء HomePageView
الذي يستخدم النموذج والقالب المسمى home.html
.
# posts/views.py
from django.views.generic import ListView
from .models import Post
class HomePageView(ListView):
model = Post
template_name = "home.html"
القوالب
لدينا خياران لموقع القالب، حيث يمكننا وضعه داخل تطبيق posts
على posts/templates/posts/home.html
ولكني أجد أن هذا الهيكل زائد عن الحاجة. بالإضافة إلى أنه من الصعب التفكير في القوالب عندما تكون جميعها مدفونة داخل التطبيقات الخاصة بها.
لذلك عادةً ما أقوم بدلاً من ذلك بإنشاء دليل قوالب على مستوى المشروع.
(.venv) > mkdir templates
كما سنطلب من Django أن يبحث هنا عن أي قالب عن طريق تحديث إعداد TEMPLATES
داخل config/settings.py
.
# config/settings.py
TEMPLATES = [
{
...
"DIRS": [BASE_DIR / "templates"], # جديد
...
},
]
ثم قم بإنشاء ملف قالب داخل هذا الدليل templates/home.html
، والذي سيعرض title
و image
لجميع المشاركات. تمامًا كما يفعل Instagram :).
<!-- templates/home.html -->
<h1>Django Image Uploading</h1>
<ul>
{% for post in object_list %}
<h2>{{ post.title }}</h2>
<img src="{{ post.cover.url}}" alt="{{ post.title }}">
{% endfor %}
</ul>
تأكد من أن الخادم يعمل باستخدام أمر python manage.py runserver
و توجه إلى الصفحة الرئيسية على http://127.0.0.1:8000.
و كلما قمت بإضافة منشورات إضافية بعنوان وصورة عبر المشرف فسوف تظهر على الصفحة الرئيسية.
Form
يمكننا الآن إضافة نموذج حتى يتمكن المستخدمون العاديون، الذين ليس لديهم حق الوصول إلى المسؤول، من إضافة منشورات أيضًا. وهذا يعني إنشاء صفحة جديدة بنموذج.
لنبدأ مع views.py
و سنقوم بتسمية العرض الجديد CreatePostView
والتي سيعمل على توسيع Django CreateView المدمج.
سنقوم أيضًا باستيراد Reverse_lazy للتعامل مع إعادة التوجيه إلى صفحتنا الرئيسية بعد إرسال النموذج.
ضمن العرض، نحدد model
، و form_class
الذي سنقوم بإنشائه بعد ذلك، و template_name
، وأخيرًا success_url
وهو ما نريد أن يحدث بعد الإرسال.
# posts/views.py
from django.views.generic import ListView, CreateView # جديد
from django.urls import reverse_lazy # جديد
from .forms import PostForm # جديد
from .models import Post
class HomePageView(ListView):
model = Post
template_name = "home.html"
class CreatePostView(CreateView): # جديد
model = Post
form_class = PostForm
template_name = "post.html"
success_url = reverse_lazy("home")
قم بإنشاء Posts/forms.py حتى يمكننا توسيع ModelForm المدمج في Django. كل ما نحتاجه لنموذجنا الأساسي هو تحديد النموذج الصحيح Post
والحقول التي نريد عرضها وهي title
و cover
.
# posts/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ["title", "cover"]
سنقوم بعمل صفحة مخصصة لهذا النموذج في مسار post/
.
# posts/urls.py
from django.urls import path
from .views import HomePageView, CreatePostView # جديد
urlpatterns = [
path("", HomePageView.as_view(), name="home"),
path("post/", CreatePostView.as_view(), name="add_post") # جديد
]
ثم قم بإنشاء القالب الجديد على templates/post.html
. و من المهم دائمًا إضافة csrf_token
للحماية. نحن نحدد
مما يعني أن Django سيقوم بإخراج كل حقل كعلامة فقرة.
form.as_p
<!-- templates/post.html -->
<h1>Create Post Page</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit New Post</button>
</form>
هذا كل شيء! تأكد من أن الخادم يعمل وانتقل إلى صفحة http://127.0.0.1:8000/post/.
بعد إرسال المشاركة الجديدة، ستتم إعادة توجيهك مرة أخرى إلى الصفحة الرئيسية وسترى جميع المشاركات.
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.