القائمة الرئيسية

الصفحات

كيفية برمجة تطبيق دليل مطاعم باستخدام Python Django

restaurant guide app code، How-to-code-restaurant-guide-app-in-Python-Django، How to code a restaurant guide app using Python and Django، تطبيق دليل مطاعم، برمجة تطبيق دليل مطاعم باستخدام Python، برمجة تطبيق دليل مطاعم شامل باستخدام Python Django، برمجة دليل مطاعم Python، تطوير تطبيق مطاعم Django، إنشاء موقع دليل مطاعم Python، واجهة مستخدم دليل مطاعم Django، نماذج Django للمطاعم والفئات والمواقع والأطعمة، عرض المطاعم وتفاصيلها Django، إضافة مطاعم جديدة Django، حفظ بيانات المطاعم Django، البحث عن المطاعم وتصفيتها Django، نظام تقييم المطاعم Django، نظام مستخدمين Django، مصادقة المستخدم Django، نشر تطبيق دليل مطاعم Django، إعداد Django لتطبيق مطاعم، إنشاء مشروع Django للمطاعم، نماذج Django للمطاعم، نماذج Django للفئات، نماذج Django للمواقع، نماذج Django للأطعمة، علاقات Django ForeignKey و ManyToMany، قوالب Django لعرض المطاعم وتفاصيلها، نماذج Django Forms لإضافة المطاعم والتقييمات، طرق عرض Django لعرض المطاعم وتفاصيلها وإضافتها وتقييمها، مسارات URL Django لتطبيق المطاعم، Django Admin لإدارة المطاعم والفئات والمواقع والأطعمة، تخزين صور المطاعم Django، تحسين محركات البحث SEO لتطبيق المطاعم، نشر تطبيقات Django باستخدام Gunicorn و Nginx، Python Django، دجانغو، جانغو، Python Django، كيفية برمجة تطبيق دليل مطاعم باستخدام Python Django، عرض المطاعم وتفاصيلها Django، برمجة دليل مطاعم Python،




كيفية برمجة تطبيق دليل مطاعم باستخدام Python Django



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


خطوات برمجة تطبيق دليل مطاعم باستخدام Python Django



الخطوة 1: إعداد بيئة التطوير وإنشاء مشروع Django

تأكد من تثبيت Python و pip على جهازك. ثم قم بتثبيت Django :
pip install django
-
* أنشئ مشروع Django جديدًا باسم restaurant_directory :
django-admin startproject restaurant_directory
cd restaurant_directory
--
* أنشئ تطبيقًا داخل المشروع باسم restaurants :
python manage.py startapp restaurants
--

الخطوة 2: تعريف نماذج البيانات (Models)

في ملف restaurants/models.py، سنقوم بتعريف نماذج البيانات
 الأساسية للمطاعم والفئات والمواقع والأطعمة والتقييمات :




Python

from django.db import models
from django.contrib.auth.models import User
from django.utils.text import slugify

class Category(models.Model):
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=100, unique=True, blank=True)

    class Meta:
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

class Location(models.Model):
    name = models.CharField(max_length=255, unique=True)
    slug = models.SlugField(max_length=255, unique=True, blank=True)
    latitude = models.FloatField(blank=True, null=True)
    longitude = models.FloatField(blank=True, null=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

class Restaurant(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    location = models.ForeignKey(Location, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, unique=True, blank=True)
    description = models.TextField(blank=True, null=True)
    address = models.CharField(max_length=255)
    phone_number = models.CharField(max_length=20, blank=True, null=True)
    website = models.URLField(blank=True, null=True)
    opening_hours = models.TextField(blank=True, null=True)
    image = models.ImageField(upload_to='restaurants/', blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

class FoodItem(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, related_name='menu')
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True, null=True)
    price = models.DecimalField(max_digits=8, decimal_places=2)

    def __str__(self):
        return self.name

class Review(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, related_name='reviews')
    rating = models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')])
    comment = models.TextField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('user', 'restaurant')
        ordering = ['-created_at']

    def __str__(self):
        return f"Review by {self.user.username} for {self.restaurant.name}"


--

* أضف تطبيق restaurants إلى قائمة INSTALLED_APPS في
 ملف restaurant_directory/settings.py :

Python

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'restaurants', # إضافة تطبيق restaurants هنا
]
--

* قم بإنشاء التغييرات وتنفيذها :
python manage.py makemigrations restaurants
python manage.py migrate
--




الخطوة 3: إنشاء واجهة المستخدم (Templates)

أنشئ مجلدًا باسم templates داخل مجلد تطبيق restaurants. 
ثم أنشئ ملفات HTML التالية:
* restaurants/templates/restaurants/restaurant_list.html: 
لعرض قائمة المطاعم:

HTML

<!DOCTYPE html>
<html>
<head>
    <title>دليل المطاعم</title>
</head>
<body>
    <h1>المطاعم المتاحة</h1>
    <ul>
        {% for restaurant in restaurants %}
            <li><a href="{% url 'restaurant_detail' restaurant.slug %}">{{ restaurant.name }}</a> - {{ restaurant.location.name }}</li>
        {% empty %}
            <li>لا توجد مطاعم متاحة حاليًا.</li>
        {% endfor %}
    </ul>
    <a href="{% url 'add_restaurant' %}">أضف مطعمًا جديدًا</a>
</body>
</html>
--

* restaurants/templates/restaurants/restaurant_detail.html : 
لعرض تفاصيل المطعم وقائمة الطعام والتقييمات :




HTML

<!DOCTYPE html>
<html>
<head>
    <title>{{ restaurant.name }}</title>
</head>
<body>
    <h1>{{ restaurant.name }}</h1>
    {% if restaurant.image %}
        <img src="{{ restaurant.image.url }}" alt="{{ restaurant.name }}" style="max-width: 400px;">
    {% endif %}
    <p>الموقع: {{ restaurant.location.name }}</p>
    <p>العنوان: {{ restaurant.address }}</p>
    {% if restaurant.phone_number %}
        <p>رقم الهاتف: {{ restaurant.phone_number }}</p>
    {% endif %}
    {% if restaurant.website %}
        <p>الموقع الإلكتروني: <a href="{{ restaurant.website }}">{{ restaurant.website }}</a></p>
    {% endif %}
    {% if restaurant.opening_hours %}
        <p>ساعات العمل: {{ restaurant.opening_hours }}</p>
    {% endif %}
    {% if restaurant.description %}
        <p>الوصف: {{ restaurant.description }}</p>
    {% endif %}

    <h2>قائمة الطعام</h2>
    {% if restaurant.menu.all %}
        <ul>
            {% for item in restaurant.menu.all %}
                <li>{{ item.name }} - {{ item.price }}
                    {% if item.description %}
                        <p>{{ item.description }}</p>
                    {% endif %}
                </li>
            {% endfor %}
        </ul>
    {% else %}
        <p>لا توجد عناصر في قائمة الطعام حاليًا.</p>
    {% endif %}

    <h2>التقييمات</h2>
    {% if restaurant.reviews.all %}
        <ul>
            {% for review in restaurant.reviews.all %}
                <li>{{ review.user.username }} - التقييم: {{ review.rating }}
                    {% if review.comment %}
                        <p>{{ review.comment }}</p>
                    {% endif %}
                    {% if request.user.is_authenticated and request.user == review.user %}
                        <a href="{% url 'edit_review' restaurant.slug review.id %}">تعديل التقييم</a>
                    {% endif %}
                </li>
            {% endfor %}
        </ul>
    {% else %}
        <p>لا توجد تقييمات لهذا المطعم حتى الآن.</p>
    {% endif %}

    {% if request.user.is_authenticated %}
        <h3>إضافة تقييم</h3>
        <form method="post" action="{% url 'add_review' restaurant.slug %}">
            {% csrf_token %}
            {{ review_form.as_p }}
            <button type="submit">إضافة تقييم</button>
        </form>
    {% else %}
        <p><a href="{% url 'login' %}">سجل الدخول</a> لإضافة تقييم.</p>
    {% endif %}

    <a href="{% url 'restaurant_list' %}">العودة إلى قائمة المطاعم</a>
</body>
</html>



--

* restaurants/templates/restaurants/add_restaurant.html : 
لنموذج إضافة مطعم جديد:

HTML

<!DOCTYPE html>
<html>
<head>
    <title>إضافة مطعم جديد</title>
</head>
<body>
    <h1>أضف مطعمًا جديدًا</h1>
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ restaurant_form.as_p }}
        <button type="submit">إضافة المطعم</button>
    </form>
    <a href="{% url 'restaurant_list' %}">العودة إلى قائمة المطاعم</a>
</body>
</html>
--

* restaurants/templates/restaurants/edit_review.html: 
لنموذج تعديل التقييم:

HTML

<!DOCTYPE html>
<html>
<head>
    <title>تعديل التقييم</title>
</head>
<body>
    <h1>تعديل التقييم</h1>
    <form method="post">
        {% csrf_token %}
        {{ review_form.as_p }}
        <button type="submit">حفظ التعديلات</button>
    </form>
    <a href="{% url 'restaurant_detail' restaurant.slug %}">العودة إلى تفاصيل المطعم</a>
</body>
</html>
--

الخطوة 4: إنشاء النماذج (Forms)

في ملف restaurants/forms.py (إذا لم يكن موجودًا، قم بإنشائه) :

Python

from django import forms
from .models import Restaurant, FoodItem, Review

class AddRestaurantForm(forms.ModelForm):
    class Meta:
        model = Restaurant
        fields = ['category', 'location', 'name', 'description', 'address', 'phone_number', 'website', 'opening_hours', 'image']

class AddFoodItemForm(forms.ModelForm):
    class Meta:
        model = FoodItem
        fields = ['name', 'description', 'price']

class ReviewForm(forms.ModelForm):
    rating = forms.ChoiceField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')], widget=forms.RadioSelect)
    class Meta:
        model = Review
        fields = ['rating', 'comment']
--

الخطوة 5: إنشاء طرق العرض (Views)

في ملف restaurants/views.py:




Python

from django.shortcuts import render, redirect, get_object_or_404
from .models import Restaurant, Category, Location, FoodItem, Review
from .forms import AddRestaurantForm, AddFoodItemForm, ReviewForm
from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.contrib import messages

def restaurant_list(request):
    restaurants = Restaurant.objects.filter(is_active=True).order_by('name')
    return render(request, 'restaurants/restaurant_list.html', {'restaurants': restaurants})

def restaurant_detail(request, slug):
    restaurant = get_object_or_404(Restaurant, slug=slug, is_active=True)
    review_form = ReviewForm()
    return render(request, 'restaurants/restaurant_detail.html', {'restaurant': restaurant, 'review_form': review_form})

@login_required
def add_restaurant(request):
    if request.method == 'POST':
        restaurant_form = AddRestaurantForm(request.POST, request.FILES)
        if restaurant_form.is_valid():
            restaurant = restaurant_form.save(commit=False)
            restaurant.user = request.user
            restaurant.save()
            messages.success(request, 'تمت إضافة المطعم بنجاح.')
            return redirect('restaurant_detail', slug=restaurant.slug)
        else:
            messages.error(request, 'حدث خطأ أثناء إضافة المطعم. يرجى التحقق من النموذج.')
    else:
        restaurant_form = AddRestaurantForm()
    return render(request, 'restaurants/add_restaurant.html', {'restaurant_form': restaurant_form})

@login_required
def add_review(request, restaurant_slug):
    restaurant = get_object_or_404(Restaurant, slug=restaurant_slug, is_active=True)
    if request.method == 'POST':
        review_form = ReviewForm(request.POST)
        if review_form.is_valid():
            review = review_form.save(commit=False)
            review.user = request.user
            review.restaurant = restaurant
            try:
                review.save()
                messages.success(request, 'تمت إضافة تقييمك بنجاح.')
                return redirect('restaurant_detail', slug=restaurant.slug)
            except Exception as e:
                messages.error(request, 'لقد قمت بتقييم هذا المطعم بالفعل.')
                return redirect('restaurant_detail', slug=restaurant.slug)
        else:
            messages.error(request, 'حدث خطأ أثناء إضافة تقييمك. يرجى التحقق من النموذج.')
    return redirect('restaurant_detail', slug=restaurant.slug)

@login_required
def edit_review(request, restaurant_slug, review_id):
    restaurant = get_object_or_404(Restaurant, slug=restaurant_slug, is_active=True)
    review = get_object_or_404(Review, id=review_id, user=request.user, restaurant=restaurant)
    if request.method == 'POST':
        review_form = ReviewForm(request.POST, instance=review)
        if review_form.is_valid():
            review_form.save()
            messages.success(request, 'تم تعديل تقييمك بنجاح.')
return redirect('restaurant_detail', slug=restaurant.slug)
else:
messages.error(request, 'حدث خطأ أثناء تعديل تقييمك. يرجى التحقق من النموذج.')
else:
review_form = ReviewForm(instance=review)
return render(request, 'restaurants/edit_review.html', {'review_form': review_form, 'restaurant': restaurant})


--

الخطوة 6: تعريف مسارات URL (URLs)

في ملف `restaurants/urls.py` (إذا لم يكن موجودًا، قم بإنشائه):




python

from django.urls import path
from . import views

urlpatterns = [
    path('', views.restaurant_list, name='restaurant_list'),
    path('add/', views.add_restaurant, name='add_restaurant'),
    path('<slug:slug>/', views.restaurant_detail, name='restaurant_detail'),
    path('<slug:restaurant_slug>/review/', views.add_review, name='add_review'),
    path('<slug:restaurant_slug>/review/edit/<int:review_id>/', views.edit_review, name='edit_review'),
]
--

* قم بتضمين مسارات تطبيق restaurants في ملف
 restaurant_directory/urls.py :
Python

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.shortcuts import redirect

urlpatterns = [
    path('admin/', admin.site.urls),
    path('restaurants/', include('restaurants.urls')),
    path('accounts/', include('django.contrib.auth.urls')), # لتسجيل الدخول والخروج
    path('', lambda request: redirect('/restaurants/')), # إعادة التوجيه إلى قائمة المطاعم عند الوصول إلى الجذر
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
--

* تأكد من إضافة 'django.contrib.auth' إلى
 INSTALLED_APPS في settings.py.

الخطوة 7: إنشاء واجهة إدارة (Django Admin)

لتسهيل إدارة المطاعم والفئات والمواقع والأطعمة والتقييمات،
 قم بتسجيل النماذج في Django Admin في ملف restaurants/admin.py :




Python

from django.contrib import admin
from .models import Restaurant, Category, Location, FoodItem, Review

class FoodItemInline(admin.TabularInline):
    model = FoodItem
    extra = 3

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('name', 'slug')
    prepopulated_fields = {'slug': ('name',)}

@admin.register(Location)
class LocationAdmin(admin.ModelAdmin):
    list_display = ('name', 'slug', 'latitude', 'longitude')
    prepopulated_fields = {'slug': ('name',)}

@admin.register(Restaurant)
class RestaurantAdmin(admin.ModelAdmin):
    list_display = ('name', 'category', 'location', 'user', 'is_active', 'created_at')
    list_filter = ('category', 'location', 'is_active')
    search_fields = ('name', 'description', 'address')
    prepopulated_fields = {'slug': ('name',)}
    inlines = [FoodItemInline]

@admin.register(FoodItem)
class FoodItemAdmin(admin.ModelAdmin):
    list_display = ('name', 'restaurant', 'price')
    list_filter = ('restaurant',)
    search_fields = ('name', 'description')

@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
    list_display = ('user', 'restaurant', 'rating', 'created_at')
    list_filter = ('restaurant', 'rating')
    search_fields = ('comment', 'user__username', 'restaurant__name')


--

* قم بإنشاء مستخدم مسؤول إذا لم يكن لديك واحدًا بالفعل :
python manage.py createsuperuser
--
* ثم قم بتشغيل خادم التطوير وقم بزيارة http://127.0.0.1:8000/admin/ ل
تسجيل الدخول وإدارة المطاعم والفئات والمواقع والأطعمة والتقييمات.

الخطوة 8: حفظ بيانات المطاعم والتقييمات

يتم حفظ بيانات المطاعم عند تقديم نموذج إضافة المطعم (AddRestaurantForm)
 في طريقة العرض add_restaurant. يتم إنشاء كائن
 Restaurant جديد مرتبط بالمستخدم والفئة والموقع.

يتم حفظ بيانات التقييمات عند تقديم نموذج التقييم (ReviewForm)
 في طريقة العرض add_review. يتم إنشاء كائن Review جديد مرتبط بالمستخدم 
والمطعم والتقييم والتعليق. Django ORM يتولى عملية التفاعل مع قاعدة
 البيانات وحفظ البيانات بناءً على تعريف النماذج والعلاقات بينها.

الخطوة 9: نشر التطبيق

لنشر تطبيق Django، يمكنك اتباع الخطوات العامة التالية (باستخدام Gunicorn و Nginx كمثال):
* تثبيت Gunicorn :
pip install gunicorn
--
* اختبار Gunicorn: انتقل إلى مجلد مشروع Django وقم بتشغيل:
gunicorn restaurant_directory.wsgi:application
--
* تثبيت Nginx :
sudo apt update
sudo apt install nginx
--
* تكوين Nginx: قم بإنشاء ملف تكوين جديد للموقع الخاص بك في /etc/nginx/sites-available/ (مثل restaurant_directory) وقم بربطه بـ /etc/nginx/sites-enabled/. مثال على التكوين:
Nginx

server {
    listen 80;
    server_name your_domain_or_IP;
    location /static/ {
        alias /path/to/your/project/staticfiles/;
    }
    location /media/ {
        alias /path/to/your/project/media/;
    }
    location / {
        proxy_pass [http://127.0.0.1:8000](http://127.0.0.1:8000);
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
--

استبدل your_domain_or_IP بعنوان نطاقك أو عنوان IP الخاص بالخادم،
 و /path/to/your/project/staticfiles/ بالمسار
 الفعلي لمجلد الملفات الثابتة الخاص بك، و 
/path/to/your/project/media/ بالمسار الفعلي لمجلد الوسائط الخاص بك.

* جمع الملفات الثابتة :
python manage.py collectstatic
--
تكوين نظام إدارة العمليات (مثل systemd) لتشغيل Gunicorn تلقائيًا.
* إعادة تشغيل Nginx :
sudo systemctl restart nginx
--
تأمين الخادم الخاص بك (مثل إعداد جدار حماية وتكوين HTTPS باستخدام Let's Encrypt).

* الخلاصة :

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


جدول المحتويات