بناء تطبيق مدونة مع جانغو

في هذا الدرس، سنقوم بإنشاء تطبيق مدونة باستخدام Django يسمح للمستخدمين بإنشاء المشاركات وتحريرها وحذفها. ستحتوي الصفحة الرئيسية جميع منشورات المدونة، وستكون هناك صفحة تفاصيل مخصصة لكل مشاركة على حدة. Django قادر على إنشاء أشياء أكثر تقدمًا، لكن إنشاء مدونة يعد خطوة أولى ممتازة للحصول على فهم جيد لإطار العمل. الغرض من هذا الفصل هو الحصول على فكرة عامة عن عمل جانغو.

هنا نظرة خاطفة على ما سنقوم ببناءه.

الدرس يتكون من عدة اجزاء وهذا الجزء الأول من السلسلة:

  • بناء تطبيق مدونة مع جانغو.

قبل البدء، أتمنى أن تكون لديك بالفعل فكرة مختصرة عن إطار العمل الذي سنستخدمه لهذا المشروع، إذا لم يكن الأمر كذلك، فيمكنك الإطلاع على القائمة المجانية من دروس جانغو .

جانغو هو إطار ويب مفتوح المصدر، مكتوب بلغة بايثون، ويتبع النمط المعماري لنموذج عرض القالب. لذلك يجب تثبيت لغة بايثون على جهازك. لسوء الحظ، كان هناك تحديث مهم لبايثون منذ عدة سنوات مما أدى إلى انقسام كبير بين إصدارات بايثون، و أصبح هناك بايثون 2 الإصدار القديم و بايثون 3.

نظرًا لأن Python 3 هو الإصدار الحالي و المعتمد على نطاق واسع ويتم تناوله على أنه مستقبل Python، فقد طرح Django تحديثًا مهمًا، والآن أصبحت جميع الإصدارات بعد Django 2.0 متوافقة فقط مع Python 3.x. ولذلك فإن هذا الدرس مخصص فقط لـ Python 3.x. لذلك تأكد من تثبيت Python 3 على جهازك.

إنشاء وتفعيل البيئة الافتراضية

أثناء إنشاء مشاريع بايثون، من الممارسات الجيدة العمل في بيئات افتراضية للحفاظ على مشروعك وتبعيته معزولة عن جهازك.

virtualenv django
Scripts\activate.bat

الآن يجب أن ترى (Django) مسبوقة في بداية السطر على الطرفية، مما يشير إلى أنه تم تنشيط البيئة الافتراضية بنجاح.

تثبيت جانغو في البيئة الافتراضية

إذا قمت بالفعل بتثبيت Django، فيمكنك تخطي هذا القسم والانتقال مباشرة إلى قسم إعداد المشروع. لتثبيت Django على بيئتك الافتراضية، قم بتشغيل الأمر أدناه

pip install Django

سيؤدي هذا إلى تثبيت أحدث إصدار من Django في بيئتنا الافتراضية.

إعداد المشروع

في مساحة العمل الخاصة بك، قم بإنشاء دليل يسمى mysite وانتقل إليه.

cd Desktop
mkdir mysite
cd mysite

الآن قم بتشغيل الأمر التالي في Shell الخاص بك لإنشاء مشروع Django.

django-admin startproject mysite

سيؤدي هذا إلى إنشاء بنية مشروع تحتوي على العديد من الدلائل و برامج بايثون.

├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py

لمعرفة المزيد عن وظيفة الملفات: إنشاء مشروع جانغو – الطريق الصحيح.

بعد ذلك، نحتاج إلى إنشاء تطبيق Django يسمى blog.

انتقل إلى الدليل الخارجي حيث يوجد البرنامج النصي Manage.py وقم بتشغيل الأمر التالي:

cd mysite
python manage.py startapp blog

سيؤدي ذلك إلى إنشاء تطبيق يسمى blog.

├── db.sqlite3
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py
└── blog
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

نحتاج الآن إلى إبلاغ Django بأنه قد تم إنشاء تطبيق جديد، إفتح ملف settings.py، ثم انتقل إلى قسم التطبيقات المثبتة، والذي يجب أن يحتوي على بعض التطبيقات المثبتة بالفعل.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

أضف التطبيق التي تم إنشاؤه حديثًا في الأسفل.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog'
]

بعد ذلك، قم بإجراء الهجرة.

python manage.py migrate

سيؤدي هذا إلى تطبيق جميع عمليات الترحيل غير المطبقة على قاعدة بيانات SQLite والتي تأتي مع تثبيت Django.

لنختبر إعداداتنا عن طريق تشغيل خادم التطوير المدمج في Django.

python manage.py runserver

افتح متصفحك وانتقل إلى هذا العنوان http://127.0.0.1:8000/ إذا سار كل شيء على ما يرام، فيجب أن تشاهد هذه الصفحة.

الصفحة الترحيبية لجانغو
الصفحة الترحيبية لجانغو

نماذج قواعد البيانات

سنقوم الآن بتعريف نماذج البيانات لمدونتنا. النموذج هو فئة بايثون التي تصنف django.db.models.Model، حيث تمثل كل سمة حقل قاعدة بيانات. باستخدام دالة الفئة الفرعية هذه، يمكننا تلقائيًا الوصول إلى كل شيء داخل django.db.models.Models ويمكننا إضافة حقول و توابع إضافية حسب الرغبة. سيكون لدينا نموذج Post في قاعدة البيانات لتخزين المنشورات.

from django.db import models
from django.contrib.auth.models import User


STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

في الجزء العلوي، نقوم باستيراد  models ثم إنشاء فئة فرعية models.Model مثل أي مدونة نموذجية، سيكون لكل تدوينة عنوان ورقم ثابت واسم المؤلف والطابع الزمني أو تاريخ نشر المقالة أو آخر مرة محدث.

لاحظ كيف أعلنا عن صف STATUS للمنشور لإبقاء المسودة والمشاركات المنشورة منفصلة عندما نعرضها باستخدام القوالب.

تحتوي فئة Meta داخل النموذج على بيانات تعريف. نطلب من Django فرز النتائج في حقل created_on بترتيب تنازلي افتراضيًا عندما نقوم بالاستعلام عن قاعدة البيانات. نحدد ترتيبًا تنازليًا باستخدام البادئة السالبة. ومن خلال القيام بذلك، ستظهر المشاركات المنشورة الأخيرة أولاً.

التابع__str__()  هي التمثيل الافتراضي للكائن الذي يمكن قراءته بواسطة الإنسان. سيستخدمه Django في العديد من الأماكن، مثل موقع الإدارة.

الآن بعد أن تم إنشاء نموذج قاعدة البيانات الجديد، نحتاج إلى إنشاء سجل ترحيل جديد له وترحيل التغيير إلى قاعدة البيانات الخاصة بنا.

(django) $ python manage.py makemigrations
(django) $ python manage.py migrate

إنشاء موقع الإدارة

سنقوم بإنشاء لوحة إدارة لإنشاء المشاركات وإدارتها. لحسن الحظ، يأتي Django مزودًا بواجهة إدارية مدمجة لمثل هذه المهام.

من أجل استخدام مسؤول Django أولاً، نحتاج إلى إنشاء مستخدم متميز عن طريق تشغيل الأمر التالي:

python manage.py createsuperuser

سيُطلب منك إدخال البريد الإلكتروني وكلمة المرور واسم المستخدم. لاحظ أنه لأسباب أمنية، لن تكون كلمة المرور مرئية.

Username (leave blank to use 'user'): admin
Email address: admin@gamil.com
Password:
Password (again):

أدخل أي تفاصيل يمكنك دائمًا تغييرها لاحقًا. بعد ذلك أعد تشغيل خادم التطوير وانتقل إلى العنوان http://127.0.0.1:8000/admin/

python manage.py runserver

يجب أن تشاهد صفحة تسجيل الدخول، أدخل التفاصيل التي قدمتها للمستخدم المتميز.

موقع إدارة جانغو
موقع إدارة جانغو

بعد تسجيل الدخول، يجب أن تشاهد لوحة الإدارة الأساسية التي تحتوي على نماذج المجموعات والمستخدمين التي تأتي من إطار عمل مصادقة Django الموجود في django.contrib.auth.

إضافة نماذج إلى موقع الإدارة

افتح ملف blog/admin.py وقم بتسجيل نموذج Post هناك كما يلي:

from django.contrib import admin
from .models import Post

admin.site.register(Post)

احفظ الملف وقم بتحديث الصفحة حيث يجب أن تشاهد نموذج المنشورات هناك.

لنقم الآن بإنشاء أول مشاركة في مدونتنا، انقر على أيقونة “إضافة” بجانب “النشر” والتي ستنقلك إلى صفحة أخرى حيث يمكنك إنشاء مشاركة. املأ النماذج المعنية وأنشئ أول مشاركة لك على الإطلاق.

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

يمكننا تخصيص طريقة عرض البيانات في لوحة الإدارة وفقًا لراحتنا. افتح ملف admin.py مرة أخرى واستبدله بالكود أدناه.

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}

admin.site.register(Post, PostAdmin)

سيؤدي هذا إلى جعل لوحة التحكم الإدارية لدينا أكثر كفاءة. الآن إذا قمت بزيارة قائمة المنشورات، فسوف ترى المزيد من التفاصيل حول المنشور.

إذا لاحظت على اليمين، يوجد مرشح يقوم بتصفية المنشور اعتمادًا على حالته، ويتم ذلك عن طريق طريقة list_filter.

والآن لدينا شريط بحث في أعلى القائمة، والذي سيبحث في قاعدة البيانات من خلال سمات حقول البحث. تقوم السمة الأخيرة prepopulated_fields بملء الارتباط التقريبي، والآن إذا قمت بإنشاء منشور، فسيتم ملء الارتفاع التقريبي تلقائيًا بناءً على عنوانك.

الآن بعد أن اكتمل نموذج قاعدة البيانات لدينا، نحتاج إلى إنشاء العرض وعناوين URL والقوالب الضرورية حتى نتمكن من عرض المعلومات على المدونة.

بناء العروض

عرض Django هو مجرد دالة Python التي تتلقى طلب ويب وترجع استجابة ويب. سنستخدم العرض المستند إلى الفصل ثم نعين عناوين URL لكل عرض وننشئ نموذج HTML للبيانات التي يتم إرجاعها من العرض.

افتح ملف blog/views.py وابدأ في البرمجة.

from django.views import generic
from .models import Post

class PostList(generic.ListView):
    queryset = Post.objects.filter(status=1).order_by('-created_on')
    template_name = 'index.html'

class PostDetail(generic.DetailView):
    model = Post
    template_name = 'post_detail.html'

تعرض ListViews المضمنة والتي تعد فئة فرعية من العرض العامة المستندة إلى الفئة قائمة بكائنات النموذج المحدد، نحتاج فقط إلى ذكر القالب، وبالمثل يوفر DetailView عرضًا تفصيليًا لكائن معين من النموذج.

لاحظ أنه بالنسبة لعرض PostList، قمنا بتطبيق عامل تصفية بحيث يتم عرض المنشور ذو الحالة المنشورة فقط في الواجهة الأمامية لمدونتنا. وفي نفس الاستعلام أيضًا، قمنا بترتيب جميع المشاركات حسب تاريخ إنشائها. تشير العلامة (-) قبل create_on إلى أن آخر مشاركة ستكون في الأعلى، وهكذا.

إضافة أنماط URL للعروض

نحتاج إلى تعيين عنوان URL للعروض التي قمنا بها أعلاه. عندما يقوم مستخدم بتقديم طلب لصفحة على تطبيق الويب الخاص بك، تتولى وحدة تحكم Django مهمة البحث عن العرض المقابل عبر ملف urls.py، ثم تقوم بإرجاع استجابة HTML أو خطأ 404 إذا لم يتم العثور عليه.

أنشئ ملف urls.py في دليل تطبيق مدونتك وأضف الكود التالي:

from . import views
from django.urls import path

urlpatterns = [
    path('', views.PostList.as_view(), name='home'),
    path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]

لقد قمنا بتعيين أنماط URL عامة لعروضنا باستخدام دالة path. يأخذ النمط الأول سلسلة فارغة يُشار إليها بـ ' ' ويعيد النتيجة التي تم إنشاؤها من عرض PostList والتي تعد في الأساس قائمة منشورات لصفحتنا الرئيسية وأخيرًا لدينا اسم معلمة اختياري وهو في الأساس اسم للعرض الذي سيتم استخدامه لاحقًا استخدامها في القوالب.

تعد الأسماء معلمة اختيارية، ولكن من الممارسات الجيدة إعطاء أسماء فريدة وقابلة لتذكر العرض مما يجعل عملنا سهلاً أثناء تصميم القوالب ويساعد في الحفاظ على تنظيم الأشياء مع زيادة عدد عناوين URL الخاصة بك.

بعد ذلك، لدينا التعبير العام لعروض PostDetail التي تحل الارتباط الثابت (سلسلة تتكون من أحرف أو أرقام ASCII). يستخدم Django الأقواس الزاوية < > لالتقاط القيم من عنوان URL وإرجاع صفحة تفاصيل المنشور المكافئة.

نحتاج الآن إلى تضمين عناوين URL للمدونة هذه في المشروع الفعلي للقيام بذلك، افتح الملف mysite/urls.py.

from django.contrib import admin

urlpatterns = [
    path('admin/', admin.site.urls),
]

قم أولاً باستيراد دالة include ثم قم بإضافة المسار إلى ملف urls.py الجديد في قائمة أنماط URL.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
]

الآن سيتم التعامل مع جميع الطلبات مباشرة من خلال تطبيق المدونة.

إنشاء قوالب للعروض

لقد انتهينا من النماذج و العروض، والآن نحتاج إلى إنشاء قوالب لعرض النتيجة لمستخدمينا. لاستخدام قوالب Django، نحتاج إلى تكوين إعداد القالب أولاً.

الآن في settings.py قم بالتمرير إلى TEMPLATES التي يجب أن تبدو بهذا الشكل.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

أضف الآن  BASE_DIR / 'templates' في DIRS حتى يتمكن Django من العثور على قوالبنا.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        #  Add  'TEMPLATE_DIRS' here
        
'DIRS': [
            BASE_DIR / 'templates'
        ],

        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

يمكن فصل python و HTML، حيث يتم إدخال python في العرض و HTML في القوالب. يمتلك Django لغة قالب قوية تسمح لك بتحديد كيفية عرض البيانات. يعتمد على علامات القالب ومتغيرات القالب ومرشحات القالب.

سأبدأ بملف base.html و ملف Index.html الذي يرث منه. وبعد ذلك، عندما نضيف قوالب للصفحة الرئيسية وصفحات تفاصيل المنشورات، يمكنها أيضًا أن ترث من base.html.

لنبدأ بملف base.html الذي سيحتوي على عناصر مشتركة للمدونة في أي صفحة مثل navbar و footer. كما أننا نستخدم Bootstrap لواجهة المستخدم وخط Roboto.

<!DOCTYPE html>
<html dir='rtl'>

    <head>
        <title>بايثون العربي</title>
        <link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet">
        <meta name="google" content="notranslate" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
            crossorigin="anonymous" />
    </head>

    <body>
        <style>
            body {
            font-family: "Roboto", sans-serif;
            font-size: 17px;
            background-color: #fdfdfd;
        }
        .shadow {
            box-shadow: 0 4px 2px -2px rgba(0, 0, 0, 0.1);
        }
        .btn-danger {
            color: #fff;
            background-color: #f00000;
            border-color: #dc281e;
        }
        .masthead {
            background: #3398E1;
            height: auto;
            padding-bottom: 15px;
            box-shadow: 0 16px 48px #E3E7EB;
            padding-top: 10px;
        }
    </style>

        <!-- Navigation -->
        <nav class="navbar navbar-expand-lg navbar-light bg-light shadow" id="mainNav">
            <div class="container-fluid">
                <a class="navbar-brand" href="{% url 'home' %}">بايثون العربي</a>
                <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive"
                    aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarResponsive">
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item text-black">
                            <a class="nav-link text-black font-weight-bold" href="#">عن الموقع</a>
                        </li>
                        <li class="nav-item text-black">
                            <a class="nav-link text-black font-weight-bold" href="#">سياسة الخصوصية</a>
                        </li>
                        <li class="nav-item text-black">
                            <a class="nav-link text-black font-weight-bold" href="#">إتصل بنا</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        {% block content %}
        <!-- Content Goes here -->
        {% endblock content %}
        <!-- Footer -->
        <footer class="py-3 bg-grey">
            <p class="m-0 text-dark text-center ">Copyright &copy;  >بايثون العربي  </p>
        </footer>
    </body>
</html>

هذا ملف HTML عادي باستثناء العلامات الموجودة داخل الأقواس المتعرجة { } والتي تسمى علامات القالب.

يُرجع {% url 'home' %} مرجعًا مطلقًا للمسار، ويقوم بإنشاء رابط لعرض الصفحة الرئيسية والذي يعد أيضًا عرض القائمة للمشاركات.

يحدد {% block content %} الكتلة التي يمكن تجاوزها بواسطة القوالب الفرعية، وهذا هو المكان الذي سيتم فيه إدخال المحتوى من ملف HTML الآخر.

بعد ذلك، سنقوم بإنشاء عنصر واجهة مستخدم صغير للشريط الجانبي والذي سيتم توريثه بواسطة جميع الصفحات عبر الموقع. يتم أيضًا إدراج الشريط الجانبي للإشعار في ملف base.html، مما يجعله متاحًا للصفحات التي ترث الملف الأساسي.

{% block sidebar %}

<style>
        .card{
            box-shadow: 0 16px 48px #E3E7EB;
        }

</style>

<!-- Sidebar Widgets Column -->
<div class="col-md-4 float-right ">
<div class="card my-4">
        <h5 class="card-header">About Us</h5>
    <div class="card-body">
        <p class="card-text"> تم إنشاء هذه المدونة الرائعة في الجزء العلوي من إطار العمل الكامل المفضل لدينا "Django"، تابع البرنامج التعليمي لمعرفة كيفية صنعنا ذلك..!</p>
        <a href="https://djangocentral.com/building-a-blog-application-with-django"
           class="btn btn-danger">Know more!</a>
    </div>
</div>
</div>

{% endblock sidebar %}

بعد ذلك، قم بإنشاء ملف Index.html.

{% extends "base.html" %}
{% block content %}
<style>
    body {
        font-family: "Roboto", sans-serif;
        font-size: 18px;
        background-color: #fdfdfd;
    }

    .head_text {
        color: white;
    }

    .card {
        box-shadow: 0 16px 48px #E3E7EB;
    }
</style>

<header class="masthead">
    <div class="overlay"></div>
    <div class="container">
        <div class="row">
            <div class=" col-md-8 col-md-10 mx-auto">
                <div class="site-heading">
                    <h3 class=" site-heading my-4 mt-3 text-white"> مرحبا بكم في مدونتي الرائعة </h3>
                    <p class="text-light">نحن نحب جانغو بقدر ما تحب..! &nbsp
                    </p>
                </div>
            </div>
        </div>
    </div>
</header>
<div class="container">
    <div class="row">
        <!-- Blog Entries Column -->
        <div class="col-md-8 mt-3 left">
            {% for post in post_list %}
            <div class="card mb-4">
                <div class="card-body">
                    <h2 class="card-title">{{ post.title }}</h2>
                    <p class="card-text text-muted h6">{{ post.author }} | {{ post.created_on}} </p>
                    <p class="card-text">{{post.content|slice:":200" }}</p>
                    <a href="{% url 'post_detail' post.slug  %}" class="btn btn-primary">اقرأ أكثر &rarr;</a>
                </div>
            </div>
            {% endfor %}
        </div>
        {% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
    </div>
</div>
{%endblock%}

باستخدام علامة القالب {% Extends %}، نطلب من Django أن يرث من قالب base.html. بعد ذلك، نقوم بملء كتل المحتوى الخاصة بالقالب الأساسي بالمحتوى.

لاحظ أننا نستخدم حلقة for في HTML، وهذه هي قوة قوالب Django التي تجعل HTML ديناميكيًا. تتكرر الحلقة عبر المنشورات وتعرض عنوانها وتاريخها ومؤلفها ونصها، بما في ذلك رابط في العنوان إلى عنوان URL الأساسي للمنشور.

في نص المنشور، نستخدم أيضًا مرشحات القوالب لتقييد الكلمات الموجودة في المقتطفات بـ 200 حرف. تسمح لك مرشحات القالب بتعديل المتغيرات للعرض وتبدو مثل{{ variable | filter }}.

الآن قم بتشغيل الخادم وقم بزيارة http://127.0.0.1:8000/ وسترى الصفحة الرئيسية لمدونتنا.

لنقم الآن بإنشاء قالب HTML للعرض التفصيلي لمنشوراتنا.

بقم بإنشاء ملف post_detail.html والصق كود HTML أدناه هناك.

{% extends 'base.html' %}{% block content %}

<div class="container">
  <div class="row">
    <div class="col-md-8 card mb-4  mt-3 left  top">
      <div class="card-body">
        <h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
        <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
        <p class="card-text ">{{ object.content | safe }}</p>
      </div>
    </div>
    {% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
  </div>
</div>

{% endblock content %}

في الأعلى، نحدد أن هذا القالب يرث base.html ثم نعرض body من كائن السياق الخاص بنا، والذي يجعل DetailView الوصول إليه ككائن.

الآن قم بزيارة الصفحة الرئيسية وانقر على قراءة المزيد، ومن المفترض أن يعيد توجيهك إلى صفحة تفاصيل المنشور.

اترك تعليقاً

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

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

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

Continue reading

Scroll to Top