تحميل الصور على مواقع Django

في هذا الدرس سنتعلم كيفية تحميل الصورة باستخدام 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. و يجب أن يعيد توجيهك إلى هذه الصفحة:

صفحة django admin

انقر على الرابط “+ إضافة” بجوار  Posts. يمكنك إضافة ما تريد ولكن في هذا الدرس سأقوم بنشر منشور حول تميمة Django. و يمكنك تحميلها من هنا إذا أردت.

إنشاء موضوع django

عند القيام بعملية “حفظ” ستتم إعادة توجيهك إلى صفحة المنشورات حيث يمكننا رؤية جميع منشوراتنا.

إنشاء موضوع django

إذا نظرت داخل مجلد  media المحلي في مشروعك، فسترى أسفل  images أن هناك الآن ملف الصورة  djangopony.png. يرى! و هذا هو ما سيفعله  MEDIA_URL.

حسنًا، في هذه المرحلة نكون قد انتهينا من الأساسيات. ولكن دعونا نخطو خطوة إلى الأمام ونعرض منشوراتنا بإعداد كل من ملفات  urls.pyviews.py والقوالب.

عناوين URL

الشيء المحير في Django هو أنك غالبًا ما تحتاج إلى 4 ملفات مختلفة ولكن مترابطة لصفحة ويب واحدة: models.pyurls.pyviews.py، وملف  html للقالب.

أجد أنه من السهل التفكير في هذا الأمر من خلال الترتيب التالي : النماذج -> عناوين url -> العرض -> ملفات القوالب. وبما أننا إنتهينا من النموذج فهذا يعني أننا سنتوجه لمسارات عناوين URL.

سنحتاج إلى تحديثين لملف  urls.py. الأول في ملف config/urls.py على مستوى المشروع، نحتاج إلى إضافة عمليات استيراد  settingsinclude،  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 للحماية. نحن نحدد  form.as_pمما يعني أن Django سيقوم بإخراج كل حقل كعلامة فقرة.

<!-- 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/.

إنشاء موضوع جديد django

بعد إرسال المشاركة الجديدة، ستتم إعادة توجيهك مرة أخرى إلى الصفحة الرئيسية وسترى جميع المشاركات.


اكتشاف المزيد من بايثون العربي

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

Scroll to Top

اكتشاف المزيد من بايثون العربي

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading