diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 819c119..f8c2ac2 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index becc875..4543ff8 100644 Binary files a/core/__pycache__/forms.cpython-311.pyc and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 7b76646..57e069a 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 4510127..0124c63 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index c589342..a3863d8 100644 --- a/core/admin.py +++ b/core/admin.py @@ -3,20 +3,20 @@ from .models import Profile, Parcel, Country, Governate, City @admin.register(Country) class CountryAdmin(admin.ModelAdmin): - list_display = ('name',) - search_fields = ('name',) + list_display = ('name_en', 'name_ar') + search_fields = ('name_en', 'name_ar') @admin.register(Governate) class GovernateAdmin(admin.ModelAdmin): - list_display = ('name', 'country') + list_display = ('name_en', 'name_ar', 'country') list_filter = ('country',) - search_fields = ('name',) + search_fields = ('name_en', 'name_ar') @admin.register(City) class CityAdmin(admin.ModelAdmin): - list_display = ('name', 'governate') + list_display = ('name_en', 'name_ar', 'governate') list_filter = ('governate__country', 'governate') - search_fields = ('name',) + search_fields = ('name_en', 'name_ar') @admin.register(Profile) class ProfileAdmin(admin.ModelAdmin): @@ -26,7 +26,7 @@ class ProfileAdmin(admin.ModelAdmin): @admin.register(Parcel) class ParcelAdmin(admin.ModelAdmin): - list_display = ('tracking_number', 'shipper', 'carrier', 'status', 'created_at') - list_filter = ('status', 'pickup_country', 'delivery_country') + list_display = ('tracking_number', 'shipper', 'carrier', 'status', 'payment_status', 'created_at') + list_filter = ('status', 'payment_status', 'pickup_country', 'delivery_country') search_fields = ('tracking_number', 'shipper__username', 'carrier__username', 'receiver_name') - readonly_fields = ('tracking_number', 'created_at', 'updated_at') + readonly_fields = ('tracking_number', 'created_at', 'updated_at') \ No newline at end of file diff --git a/core/forms.py b/core/forms.py index 552138d..030dfac 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,6 +1,7 @@ from django import forms from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ +from django.utils.translation import get_language from .models import Profile, Parcel, Country, Governate, City class UserRegistrationForm(forms.ModelForm): @@ -25,23 +26,28 @@ class UserRegistrationForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + lang = get_language() + name_field = 'name_ar' if lang == 'ar' else 'name_en' + + self.fields['country'].queryset = Country.objects.all().order_by(name_field) + if 'country' in self.data: try: country_id = int(self.data.get('country')) - self.fields['governate'].queryset = Governate.objects.filter(country_id=country_id).order_by('name') + self.fields['governate'].queryset = Governate.objects.filter(country_id=country_id).order_by(name_field) except (ValueError, TypeError): pass elif self.instance.pk and hasattr(self.instance, 'profile') and self.instance.profile.country: - self.fields['governate'].queryset = self.instance.profile.country.governate_set.order_by('name') + self.fields['governate'].queryset = self.instance.profile.country.governate_set.order_by(name_field) if 'governate' in self.data: try: governate_id = int(self.data.get('governate')) - self.fields['city'].queryset = City.objects.filter(governate_id=governate_id).order_by('name') + self.fields['city'].queryset = City.objects.filter(governate_id=governate_id).order_by(name_field) except (ValueError, TypeError): pass elif self.instance.pk and hasattr(self.instance, 'profile') and self.instance.profile.governate: - self.fields['city'].queryset = self.instance.profile.governate.city_set.order_by('name') + self.fields['city'].queryset = self.instance.profile.governate.city_set.order_by(name_field) def clean_password_confirm(self): password = self.cleaned_data.get('password') @@ -110,6 +116,13 @@ class ParcelForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + lang = get_language() + name_field = 'name_ar' if lang == 'ar' else 'name_en' + + # Set querysets for countries + self.fields['pickup_country'].queryset = Country.objects.all().order_by(name_field) + self.fields['delivery_country'].queryset = Country.objects.all().order_by(name_field) + # Pickup self.fields['pickup_governate'].queryset = Governate.objects.none() self.fields['pickup_city'].queryset = City.objects.none() @@ -117,14 +130,14 @@ class ParcelForm(forms.ModelForm): if 'pickup_country' in self.data: try: country_id = int(self.data.get('pickup_country')) - self.fields['pickup_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by('name') + self.fields['pickup_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by(name_field) except (ValueError, TypeError): pass if 'pickup_governate' in self.data: try: gov_id = int(self.data.get('pickup_governate')) - self.fields['pickup_city'].queryset = City.objects.filter(governate_id=gov_id).order_by('name') + self.fields['pickup_city'].queryset = City.objects.filter(governate_id=gov_id).order_by(name_field) except (ValueError, TypeError): pass @@ -135,13 +148,13 @@ class ParcelForm(forms.ModelForm): if 'delivery_country' in self.data: try: country_id = int(self.data.get('delivery_country')) - self.fields['delivery_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by('name') + self.fields['delivery_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by(name_field) except (ValueError, TypeError): pass if 'delivery_governate' in self.data: try: gov_id = int(self.data.get('delivery_governate')) - self.fields['delivery_city'].queryset = City.objects.filter(governate_id=gov_id).order_by('name') + self.fields['delivery_city'].queryset = City.objects.filter(governate_id=gov_id).order_by(name_field) except (ValueError, TypeError): - pass \ No newline at end of file + pass diff --git a/core/migrations/0005_remove_city_name_remove_country_name_and_more.py b/core/migrations/0005_remove_city_name_remove_country_name_and_more.py new file mode 100644 index 0000000..b7531ba --- /dev/null +++ b/core/migrations/0005_remove_city_name_remove_country_name_and_more.py @@ -0,0 +1,55 @@ +# Generated by Django 5.2.7 on 2026-01-25 10:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_parcel_payment_status_parcel_price_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='city', + name='name', + ), + migrations.RemoveField( + model_name='country', + name='name', + ), + migrations.RemoveField( + model_name='governate', + name='name', + ), + migrations.AddField( + model_name='city', + name='name_ar', + field=models.CharField(default='', max_length=100, verbose_name='Name (Arabic)'), + ), + migrations.AddField( + model_name='city', + name='name_en', + field=models.CharField(default='', max_length=100, verbose_name='Name (English)'), + ), + migrations.AddField( + model_name='country', + name='name_ar', + field=models.CharField(default='', max_length=100, verbose_name='Name (Arabic)'), + ), + migrations.AddField( + model_name='country', + name='name_en', + field=models.CharField(default='', max_length=100, verbose_name='Name (English)'), + ), + migrations.AddField( + model_name='governate', + name='name_ar', + field=models.CharField(default='', max_length=100, verbose_name='Name (Arabic)'), + ), + migrations.AddField( + model_name='governate', + name='name_en', + field=models.CharField(default='', max_length=100, verbose_name='Name (English)'), + ), + ] diff --git a/core/migrations/0006_alter_city_name_ar_alter_city_name_en_and_more.py b/core/migrations/0006_alter_city_name_ar_alter_city_name_en_and_more.py new file mode 100644 index 0000000..3bd216d --- /dev/null +++ b/core/migrations/0006_alter_city_name_ar_alter_city_name_en_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.7 on 2026-01-25 10:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0005_remove_city_name_remove_country_name_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='city', + name='name_ar', + field=models.CharField(max_length=100, verbose_name='Name (Arabic)'), + ), + migrations.AlterField( + model_name='city', + name='name_en', + field=models.CharField(max_length=100, verbose_name='Name (English)'), + ), + migrations.AlterField( + model_name='country', + name='name_ar', + field=models.CharField(max_length=100, verbose_name='Name (Arabic)'), + ), + migrations.AlterField( + model_name='country', + name='name_en', + field=models.CharField(max_length=100, verbose_name='Name (English)'), + ), + migrations.AlterField( + model_name='governate', + name='name_ar', + field=models.CharField(max_length=100, verbose_name='Name (Arabic)'), + ), + migrations.AlterField( + model_name='governate', + name='name_en', + field=models.CharField(max_length=100, verbose_name='Name (English)'), + ), + ] diff --git a/core/migrations/__pycache__/0005_remove_city_name_remove_country_name_and_more.cpython-311.pyc b/core/migrations/__pycache__/0005_remove_city_name_remove_country_name_and_more.cpython-311.pyc new file mode 100644 index 0000000..a16bc4e Binary files /dev/null and b/core/migrations/__pycache__/0005_remove_city_name_remove_country_name_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0006_alter_city_name_ar_alter_city_name_en_and_more.cpython-311.pyc b/core/migrations/__pycache__/0006_alter_city_name_ar_alter_city_name_en_and_more.cpython-311.pyc new file mode 100644 index 0000000..e5f7c58 Binary files /dev/null and b/core/migrations/__pycache__/0006_alter_city_name_ar_alter_city_name_en_and_more.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 6893819..7c76838 100644 --- a/core/models.py +++ b/core/models.py @@ -1,13 +1,21 @@ from django.db import models from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ +from django.utils.translation import get_language from django.db.models.signals import post_save from django.dispatch import receiver import uuid class Country(models.Model): - name = models.CharField(_('Name'), max_length=100) + name_en = models.CharField(_('Name (English)'), max_length=100) + name_ar = models.CharField(_('Name (Arabic)'), max_length=100) + @property + def name(self): + if get_language() == 'ar': + return self.name_ar + return self.name_en + def __str__(self): return self.name @@ -17,8 +25,15 @@ class Country(models.Model): class Governate(models.Model): country = models.ForeignKey(Country, on_delete=models.CASCADE, verbose_name=_('Country')) - name = models.CharField(_('Name'), max_length=100) + name_en = models.CharField(_('Name (English)'), max_length=100) + name_ar = models.CharField(_('Name (Arabic)'), max_length=100) + @property + def name(self): + if get_language() == 'ar': + return self.name_ar + return self.name_en + def __str__(self): return f"{self.name} ({self.country.name})" @@ -28,8 +43,15 @@ class Governate(models.Model): class City(models.Model): governate = models.ForeignKey(Governate, on_delete=models.CASCADE, verbose_name=_('Governate')) - name = models.CharField(_('Name'), max_length=100) + name_en = models.CharField(_('Name (English)'), max_length=100) + name_ar = models.CharField(_('Name (Arabic)'), max_length=100) + @property + def name(self): + if get_language() == 'ar': + return self.name_ar + return self.name_en + def __str__(self): return f"{self.name} ({self.governate.name})" @@ -122,4 +144,4 @@ class Parcel(models.Model): class Meta: verbose_name = _('Parcel') - verbose_name_plural = _('Parcels') + verbose_name_plural = _('Parcels') \ No newline at end of file diff --git a/core/views.py b/core/views.py index f174adf..01241e4 100644 --- a/core/views.py +++ b/core/views.py @@ -5,6 +5,7 @@ from django.contrib.auth.decorators import login_required from .models import Parcel, Profile, Country, Governate, City from .forms import UserRegistrationForm, ParcelForm from django.utils.translation import gettext_lazy as _ +from django.utils.translation import get_language from django.contrib import messages from django.http import JsonResponse from django.urls import reverse @@ -168,10 +169,16 @@ def article_detail(request): def get_governates(request): country_id = request.GET.get('country_id') - governates = Governate.objects.filter(country_id=country_id).values('id', 'name') - return JsonResponse(list(governates), safe=False) + lang = get_language() + field_name = 'name_ar' if lang == 'ar' else 'name_en' + governates = Governate.objects.filter(country_id=country_id).order_by(field_name) + data = [{'id': g.id, 'name': getattr(g, field_name)} for g in governates] + return JsonResponse(data, safe=False) def get_cities(request): governate_id = request.GET.get('governate_id') - cities = City.objects.filter(governate_id=governate_id).values('id', 'name') - return JsonResponse(list(cities), safe=False) \ No newline at end of file + lang = get_language() + field_name = 'name_ar' if lang == 'ar' else 'name_en' + cities = City.objects.filter(governate_id=governate_id).order_by(field_name) + data = [{'id': c.id, 'name': getattr(c, field_name)} for c in cities] + return JsonResponse(data, safe=False)