
كيفية برمجة موقع بيع تذاكر فعاليات باستخدام Python Django
في عالمنا المتصل، أصبحت الفعاليات جزءًا حيويًا من حياتنا الاجتماعية والثقافية.
إذا كنت تطمح لتعلم كيفية برمجة موقع فعال لبيع تذاكر الفعاليات باستخدام
Python Django، فأنت في المكان الصحيح. هذا الدليل الشامل سيرشدك خطوة بخطوة
خلال عملية إنشاء منصة ديناميكية لحجز وشراء تذاكر مختلف الفعاليات.
سنتناول كل شيء بدءًا من تصميم واجهة مستخدم جذابة لعرض الفعاليات المتاحة وأنواع التذاكر،
مرورًا بتعريف نماذج البيانات لتخزين معلومات الفعاليات والتذاكر والحجوزات، وصولًا
إلى تمكين المستخدمين من حجز التذاكر و حفظ بيانات الحجوزات، وتقديم أساسيات
معالجة الدفع، وأخيرًا نشر التطبيق ليصبح متاحًا للجمهور. انطلق معنا في هذه الرحلة
لتعلم كيفية برمجة موقع بيع تذاكر فعاليات باستخدام Python Django بكفاءة وأمان.
خطوات برمجة موقع بيع تذاكر فعاليات باستخدام Python Django
الخطوة 1: إعداد بيئة التطوير وإنشاء مشروع Django
تأكد من تثبيت Python و pip على جهازك. ثم قم بتثبيت Django:
pip install django
--
* أنشئ مشروع Django جديدًا باسم event_ticket_site:
django-admin startproject event_ticket_site
cd event_ticket_site
--
* أنشئ تطبيقًا داخل المشروع باسم tickets:
python manage.py startapp tickets
--
الخطوة 2: تعريف نماذج البيانات (Models)
في ملف tickets/models.py، سنقوم بتعريف نماذج البيانات
الأساسية للفعاليات والتذاكر والحجوزات:
Python
from django.db import modelsfrom django.contrib.auth.models import Userfrom django.utils import timezone
class Event(models.Model): name = models.CharField(max_length=255) description = models.TextField() location = models.CharField(max_length=255) start_time = models.DateTimeField() end_time = models.DateTimeField() image = models.ImageField(upload_to='events/', blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True)
def __str__(self): return self.name
class TicketType(models.Model): event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='ticket_types') name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) quantity_available = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True)
def __str__(self): return f"{self.name} - {self.event.name}"
class Booking(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) ticket_type = models.ForeignKey(TicketType, on_delete=models.CASCADE) quantity = models.IntegerField(default=1) booking_time = models.DateTimeField(auto_now_add=True)
def __str__(self): return f"Booking by {self.user.username} for {self.ticket_type.name} ({self.quantity})"
def save(self, *args, **kwargs): self.ticket_type.quantity_available -= self.quantity self.ticket_type.save() super().save(*args, **kwargs)
def delete(self, *args, **kwargs): self.ticket_type.quantity_available += self.quantity self.ticket_type.save() super().delete(*args, **kwargs)
* أضف تطبيق tickets إلى قائمة INSTALLED_APPS في
ملف event_ticket_site/settings.py:
Python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tickets', # إضافة تطبيق tickets هنا
]
--
* قم بإنشاء التغييرات وتنفيذها:
python manage.py makemigrations tickets
python manage.py migrate
--
الخطوة 3: إنشاء واجهة المستخدم (Templates)
أنشئ مجلدًا باسم templates داخل مجلد تطبيق tickets. ثم أنشئ ملفات HTML التالية:
tickets/templates/tickets/event_list.html:
لعرض قائمة الفعاليات المتاحة:
HTML
<!DOCTYPE html>
<html>
<head>
<title>قائمة الفعاليات</title>
</head>
<body>
<h1>الفعاليات القادمة</h1>
<ul>
{% for event in events %}
<li>
<h2><a href="{% url 'event_detail' event.id %}">{{ event.name }}</a></h2>
{% if event.image %}
<img src="{{ event.image.url }}" alt="{{ event.name }}" width="200">
{% endif %}
<p>الموقع: {{ event.location }}</p>
<p>الوقت: {{ event.start_time }} - {{ event.end_time }}</p>
</li>
{% empty %}
<li>لا توجد فعاليات متاحة حاليًا.</li>
{% endfor %}
</ul>
</body>
</html>
--
* tickets/templates/tickets/event_detail.html:
لعرض تفاصيل الفعالية وأنواع التذاكر ونموذج الحجز:
HTML
<!DOCTYPE html><html><head> <title>{{ event.name }}</title></head><body> <h1>{{ event.name }}</h1> {% if event.image %} <img src="{{ event.image.url }}" alt="{{ event.name }}" width="400"> {% endif %} <p>{{ event.description }}</p> <p>الموقع: {{ event.location }}</p> <p>الوقت: {{ event.start_time }} - {{ event.end_time }}</p>
<h2>أنواع التذاكر المتاحة</h2> <form method="post"> {% csrf_token %} {% for ticket_type in event.ticket_types.all %} <div> <label for="ticket_{{ ticket_type.id }}">{{ ticket_type.name }} - السعر: {{ ticket_type.price }} (المتاح: {{ ticket_type.quantity_available }})</label> <input type="number" id="ticket_{{ ticket_type.id }}" name="tickets[{{ ticket_type.id }}]" value="0" min="0" max="{{ ticket_type.quantity_available }}"> </div> {% empty %} <p>لا توجد تذاكر متاحة لهذه الفعالية حاليًا.</p> {% endfor %} <button type="submit">حجز التذاكر</button> </form> <p><a href="{% url 'event_list' %}">العودة إلى قائمة الفعاليات</a></p></body></html>
* tickets/templates/tickets/booking_confirmation.html:
لعرض تأكيد الحجز:
HTML
<!DOCTYPE html>
<html>
<head>
<title>تأكيد الحجز</title>
</head>
<body>
<h1>تم حجز تذاكرك بنجاح!</h1>
<p>رقم الحجز: {{ booking.id }}</p>
<p>الفعالية: {{ booking.ticket_type.event.name }}</p>
<p>نوع التذكرة: {{ booking.ticket_type.name }}</p>
<p>الكمية: {{ booking.quantity }}</p>
<p>وقت الحجز: {{ booking.booking_time }}</p>
<p>شكراً لحجزك!</p>
<p><a href="{% url 'event_list' %}">العودة إلى قائمة الفعاليات</a></p>
</body>
</html>
--
الخطوة 4: إنشاء النماذج (Forms)
في ملف tickets/forms.py (إذا لم يكن موجودًا، قم بإنشائه)، قد
تحتاج إلى نموذج مخصص للتحقق من صحة الحجز إذا كنت تنفذ منطقًا أكثر تعقيدًا.
في هذا المثال البسيط، سنعتمد على معالجة POST مباشرة في طريقة العرض.
الخطوة 5: إنشاء طرق العرض (Views)
في ملف tickets/views.py، سنقوم بإنشاء طرق العرض التي
تتحكم في منطق التطبيق وتعرض القوالب:
Python
from django.shortcuts import render, get_object_or_404, redirectfrom .models import Event, TicketType, Bookingfrom django.contrib.auth.decorators import login_requiredfrom django.db import transaction
def event_list(request): events = Event.objects.all() return render(request, 'tickets/event_list.html', {'events': events})
def event_detail(request, event_id): event = get_object_or_404(Event, pk=event_id) return render(request, 'tickets/event_detail.html', {'event': event})
@login_requireddef book_tickets(request, event_id): event = get_object_or_404(Event, pk=event_id) if request.method == 'POST': tickets_data = request.POST.getlist('tickets') with transaction.atomic(): for i, ticket_type in enumerate(event.ticket_types.all()): quantity = int(tickets_data[i]) if quantity > 0 and ticket_type.quantity_available >= quantity: Booking.objects.create(user=request.user, ticket_type=ticket_type, quantity=quantity) elif quantity > ticket_type.quantity_available: # يمكنك إضافة معالجة أخطاء أفضل هنا return render(request, 'tickets/event_detail.html', {'event': event, 'error': f'الكمية المطلوبة لتذكرة {ticket_type.name} غير متوفرة.'}) return redirect('booking_confirmation', booking_id=Booking.objects.filter(user=request.user).last().id) return redirect('event_detail', event_id=event_id)
@login_requireddef booking_confirmation(request, booking_id): booking = get_object_or_404(Booking, id=booking_id, user=request.user) return render(request, 'tickets/booking_confirmation.html', {'booking': booking})
الخطوة 6: تعريف مسارات URL (URLs)
في ملف tickets/urls.py (إذا لم يكن موجودًا، قم بإنشائه):
Python
from django.urls import path
from . import views
urlpatterns = [
path('', views.event_list, name='event_list'),
path('event/<int:event_id>/', views.event_detail, name='event_detail'),
path('event/<int:event_id>/book/', views.book_tickets, name='book_tickets'),
path('booking/confirmation/<int:booking_id>/', views.booking_confirmation, name='booking_confirmation'),
]
--
* قم بتضمين مسارات تطبيق tickets في ملف event_ticket_site/urls.py:
Python
from django.contrib import admin
from django.urls import path, include
from django.shortcuts import redirect
urlpatterns = [
path('admin/', admin.site.urls),
path('tickets/', include('tickets.urls')),
path('accounts/', include('django.contrib.auth.urls')), # لتسجيل الدخول والخروج
path('', lambda request: redirect('/tickets/')), # إعادة التوجيه إلى قائمة الفعاليات عند الوصول إلى الجذر
]
--
الخطوة 7: إنشاء واجهة إدارة (Django Admin)
لتسهيل إدارة الفعاليات والتذاكر والحجوزات، قم بتسجيل النماذج في
Django Admin في ملف tickets/admin.py:
Python
from django.contrib import adminfrom .models import Event, TicketType, Booking
class TicketTypeInline(admin.TabularInline): model = TicketType extra = 1
@admin.register(Event)class EventAdmin(admin.ModelAdmin): list_display = ('name', 'location', 'start_time', 'end_time') inlines = [TicketTypeInline] search_fields = ('name', 'location')
@admin.register(TicketType)class TicketTypeAdmin(admin.ModelAdmin): list_display = ('name', 'event', 'price', 'quantity_available') list_filter = ('event',) search_fields = ('name', 'event__name')
@admin.register(Booking)class BookingAdmin(admin.ModelAdmin): list_display = ('user', 'ticket_type', 'quantity', 'booking_time') list_filter = ('ticket_type__event', 'user') search_fields = ('user__username', 'ticket_type__name', 'ticket_type__event__name')
* قم بإنشاء مستخدم مسؤول إذا لم يكن لديك واحدًا بالفعل:
python manage.py createsuperuser
--
ثم قم بتشغيل خادم التطوير وقم بزيارة http://127.0.0.1:8000/admin/
لتسجيل الدخول وإدارة الفعاليات والتذاكر والحجوزات.
الخطوة 8: حفظ النقاط (بيانات الفعاليات والتذاكر والحجوزات)
يتم حفظ بيانات الفعاليات والتذاكر والحجوزات تلقائيًا في قاعدة البيانات عند
إنشائها وتعديلها من خلال واجهة Django Admin أو من خلال تفاعلات
المستخدمين مع النماذج في الواجهة الأمامية (مثل حجز التذاكر). لاحظ أننا قمنا
بتضمين منطقًا في طريقة حفظ نموذج Booking لتقليل quantity_available
في نموذج TicketType تلقائيًا، وفي طريقة حذف نموذج Booking لزيادة
quantity_available مرة أخرى. Django ORM يتولى عملية التفاعل
مع قاعدة البيانات وحفظ البيانات بناءً على تعريف النماذج والعلاقات بينها.
الخطوة 9: نشر التطبيق
لنشر تطبيق Django، يمكنك اتباع الخطوات العامة التالية (باستخدام Gunicorn و Nginx كمثال):
* تثبيت Gunicorn:
pip install gunicorn
--
* اختبار Gunicorn: انتقل إلى مجلد مشروع Django وقم بتشغيل:
gunicorn event_ticket_site.wsgi:application
--
* تثبيت Nginx:
sudo apt update
sudo apt install nginx
--
* تكوين Nginx: قم بإنشاء ملف تكوين جديد للموقع الخاص بك في
/etc/nginx/sites-available/ (مثل event_ticket_site) وقم بربطه
بـ /etc/nginx/sites-enabled/. مثال على التكوين:
Nginx
server {
listen 80;
server_name your_domain_or_IP;
location /static/ {
alias /path/to/your/project/staticfiles/;
}
location / {
proxy_pass 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/ بالمسار الفعلي لمجلد الملفات الثابتة الخاص بك.
* جمع الملفات الثابتة: قبل النشر، قم بجمع الملفات الثابتة باستخدام:
python manage.py collectstatic
--
تكوين نظام إدارة العمليات (مثل systemd) لتشغيل Gunicorn تلقائيًا.
* إعادة تشغيل Nginx:
sudo systemctl restart nginx
--
تأمين الخادم الخاص بك (مثل إعداد جدار حماية وتكوين HTTPS باستخدام Let's Encrypt).
الخطوة 10: دمج بوابات الدفع (Payment Gateway Integration)
لتمكين المستخدمين من دفع ثمن التذاكر عبر الإنترنت، ستحتاج إلى دمج
بوابة دفع مثل Stripe أو PayPal. تتضمن هذه العملية عادةً:
التسجيل للحصول على حساب مع بوابة الدفع التي اخترتها.
* تثبيت مكتبة Python الخاصة ببوابة الدفع (مثل stripe):
pip install stripe
--
* تكوين مفاتيح API الخاصة ببوابة الدفع في ملف settings.py.
إنشاء نماذج وطرق عرض جديدة للتعامل مع عملية الدفع
(إنشاء جلسات دفع، معالجة عمليات الدفع الناجحة والفاشلة).
تحديث القوالب بواجهات المستخدم اللازمة لعملية الدفع.
تأمين عملية الدفع بشكل صحيح وفقًا لوثائق بوابة الدفع ومعايير الأمان (مثل PCI DSS).
مثال بسيط لبدء عملية دفع Stripe (يتطلب تثبيت وتكوين مكتبة Stripe):
* في tickets/views.py :
Python
import stripefrom django.conf import settingsfrom django.urls import reverse
stripe.api_key = settings.STRIPE_SECRET_KEY
@login_requireddef create_checkout_session(request, event_id): event = get_object_or_404(Event, pk=event_id) line_items = [] for ticket_type in event.ticket_types.all(): quantity = int(request.POST.get(f'tickets[{ticket_type.id}]', 0)) if quantity > 0: line_items.append({ 'price_data': { 'currency': 'usd', # قم بتغيير العملة حسب الحاجة 'unit_amount': int(ticket_type.price * 100), # السعر بالسينت 'product_data': { 'name': ticket_type.name, 'description': event.name, }, }, 'quantity': quantity, })
if not line_items: return redirect('event_detail', event_id=event_id)
try: checkout_session = stripe.checkout.Session.create( customer_email=request.user.email, line_items=line_items, mode='payment', success_url=request.build_absolute_uri(reverse('payment_success')), cancel_url=request.build_absolute_uri(reverse('payment_cancel')), ) return redirect(checkout_session.url, code=303) except Exception as e: print(f"Error creating checkout session: {e}") return redirect('event_detail', event_id=event_id, error="حدث خطأ أثناء معالجة الدفع.")
def payment_success(request): return render(request, 'tickets/payment_success.html')
def payment_cancel(request): return render(request, 'tickets/payment_cancel.html')
* في tickets/urls.py :
Python
path('event/<int:event_id>/checkout/', views.create_checkout_session, name='create_checkout_session'),
path('payment/success/', views.payment_success, name='payment_success'),
path('payment/cancel/', views.payment_cancel, name='payment_cancel'),
--
* في event_detail.html :
HTML
<form method="post" action="{% url 'create_checkout_session' event.id %}">
{% csrf_token %}
{% for ticket_type in event.ticket_types.all %}
<div>
<label for="ticket_{{ ticket_type.id }}">{{ ticket_type.name }} - السعر: {{ ticket_type.price }} (المتاح: {{ ticket_type.quantity_available }})</label>
<input type="number" id="ticket_{{ ticket_type.id }}" name="tickets[{{ ticket_type.id }}]" value="0" min="0" max="{{ ticket_type.quantity_available }}">
</div>
{% empty %}
<p>لا توجد تذاكر متاحة لهذه الفعالية حاليًا.</p>
{% endfor %}
<button type="submit">الدفع وحجز التذاكر</button>
</form>
--
* الخلاصة :
لقد استعرضنا الخطوات الأساسية لبرمجة موقع فعال لبيع تذاكر الفعاليات باستخدام
Python Django، بدءًا من إنشاء واجهة المستخدم لعرض الفعاليات والتذاكر،
مرورًا بتعريف نماذج البيانات و النماذج لتمكين المستخدمين من حجز التذاكر و
حفظ هذه البيانات، وتقديم أساسيات معالجة الدفع، وصولًا إلى تقديم نظرة عامة على
عملية نشر التطبيق. تذكر أن دمج بوابات الدفع يتطلب اهتمامًا خاصًا بالأمان
واتباع أفضل الممارسات لتوفير تجربة دفع آمنة للمستخدمين. يمكنك الآن تطوير
هذا النظام بإضافة المزيد من الميزات مثل إدارة العروض الترويجية، وتكامل الخرائط،
وإشعارات البريد الإلكتروني، والمزيد. Django يوفر لك الأدوات اللازمة
لبناء منصة قوية وفعالة لبيع تذاكر الفعاليات.