changing image size in truck reg

This commit is contained in:
Flatlogic Bot 2026-01-24 07:55:38 +00:00
parent c5c799b7d6
commit d8b540ccd4
7 changed files with 187 additions and 13 deletions

View File

@ -6,6 +6,7 @@ from django.contrib import messages
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.utils.html import format_html
import os
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner, HomeSection
from .whatsapp import send_whatsapp_message
@ -38,7 +39,14 @@ class ProfileAdmin(admin.ModelAdmin):
if obj.is_expired():
return format_html('<span style="color: red; font-weight: bold;">{}</span>', _('Expired'))
days = obj.days_until_expiry()
# Profile model might not have days_until_expiry, let's check
# Based on models.py read earlier, it doesn't have it.
# It has a commented out section that seems to be a start of it.
# I'll use inline calculation
if not obj.subscription_expiry:
return format_html('<span style="color: red; font-weight: bold;">{}</span>', _('No Expiry'))
days = (obj.subscription_expiry - timezone.now().date()).days
if days <= 7:
return format_html('<span style="color: orange; font-weight: bold;">{} ({} {})</span>', _('Expiring soon'), days, _('days'))
@ -48,9 +56,56 @@ class ProfileAdmin(admin.ModelAdmin):
@admin.register(Truck)
class TruckAdmin(admin.ModelAdmin):
list_display = ('display_truck_type', 'model', 'plate_no', 'owner', 'load_capacity')
list_display = ('display_truck_type', 'model', 'plate_no', 'owner', 'load_capacity', 'is_approved')
search_fields = ('plate_no', 'owner__username', 'model')
list_filter = ('truck_type_link', 'is_approved')
readonly_fields = ('truck_picture_preview', 'registration_front_preview', 'registration_back_preview', 'driver_license_front_preview', 'driver_license_back_preview')
def truck_picture_preview(self, obj):
if obj.truck_picture:
return format_html('<img src="{}" style="max-height: 200px;"/>', obj.truck_picture.url)
return "-"
truck_picture_preview.short_description = _("Truck Picture Preview")
def _file_preview(self, field):
if not field:
return "-"
url = field.url
ext = os.path.splitext(field.name)[1].lower()
if ext in ['.jpg', '.jpeg', '.png', '.webp', '.gif']:
return format_html('<a href="{}" target="_blank"><img src="{}" style="max-height: 200px;"/></a>', url, url)
elif ext == '.pdf':
return format_html('<a href="{}" target="_blank"><i class="fa fa-file-pdf" style="font-size: 48px; color: red;"></i><br>{}</a>', url, _("View PDF Document"))
return format_html('<a href="{}" target="_blank">{}</a>', url, _("View File"))
def registration_front_preview(self, obj):
return self._file_preview(obj.registration_front)
registration_front_preview.short_description = _("Registration Front Preview")
def registration_back_preview(self, obj):
return self._file_preview(obj.registration_back)
registration_back_preview.short_description = _("Registration Back Preview")
def driver_license_front_preview(self, obj):
return self._file_preview(obj.driver_license_front)
driver_license_front_preview.short_description = _("Driver License Front Preview")
def driver_license_back_preview(self, obj):
return self._file_preview(obj.driver_license_back)
driver_license_back_preview.short_description = _("Driver License Back Preview")
fieldsets = (
(None, {'fields': ('owner', 'truck_type_link', 'is_approved')}),
(_('Details (EN)'), {'fields': ('truck_type', 'model', 'load_capacity', 'color', 'year', 'plate_no', 'registration_expiry_date')}),
(_('Details (AR)'), {'fields': ('truck_type_ar', 'model_ar', 'load_capacity_ar', 'color_ar')}),
(_('Pictures & Documents'), {'fields': (
'truck_picture', 'truck_picture_preview',
'registration_front', 'registration_front_preview',
'registration_back', 'registration_back_preview',
'driver_license_front', 'driver_license_front_preview',
'driver_license_back', 'driver_license_back_preview'
)}),
)
@admin.register(Shipment)
class ShipmentAdmin(admin.ModelAdmin):
@ -134,4 +189,4 @@ class HomeSectionAdmin(admin.ModelAdmin):
list_display = ('title', 'section_type', 'order', 'is_active')
list_editable = ('order', 'is_active')
list_filter = ('section_type', 'is_active', 'background_color')
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')

View File

@ -0,0 +1,33 @@
# Generated by Django 5.2.7 on 2026-01-24 07:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0021_appsetting_thawani_enabled'),
]
operations = [
migrations.AlterField(
model_name='truck',
name='driver_license_back',
field=models.FileField(blank=True, null=True, upload_to='docs/', verbose_name='Driver License (Back Face)'),
),
migrations.AlterField(
model_name='truck',
name='driver_license_front',
field=models.FileField(blank=True, null=True, upload_to='docs/', verbose_name='Driver License (Front Face)'),
),
migrations.AlterField(
model_name='truck',
name='registration_back',
field=models.FileField(blank=True, null=True, upload_to='docs/', verbose_name='Registration (Back Face)'),
),
migrations.AlterField(
model_name='truck',
name='registration_front',
field=models.FileField(blank=True, null=True, upload_to='docs/', verbose_name='Registration (Front Face)'),
),
]

View File

@ -5,8 +5,12 @@ from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from django.utils.translation import get_language
from django.utils import timezone
from django.core.files import File
import random
import string
import os
from io import BytesIO
from PIL import Image
class Country(models.Model):
name = models.CharField(_('Country Name'), max_length=100)
@ -127,10 +131,10 @@ class Truck(models.Model):
# Pictures
truck_picture = models.ImageField(_('Truck Picture'), upload_to='trucks/', blank=True, null=True)
registration_front = models.ImageField(_('Registration (Front Face)'), upload_to='docs/', blank=True, null=True)
registration_back = models.ImageField(_('Registration (Back Face)'), upload_to='docs/', blank=True, null=True)
driver_license_front = models.ImageField(_('Driver License (Front Face)'), upload_to='docs/', blank=True, null=True)
driver_license_back = models.ImageField(_('Driver License (Back Face)'), upload_to='docs/', blank=True, null=True)
registration_front = models.FileField(_('Registration (Front Face)'), upload_to='docs/', blank=True, null=True)
registration_back = models.FileField(_('Registration (Back Face)'), upload_to='docs/', blank=True, null=True)
driver_license_front = models.FileField(_('Driver License (Front Face)'), upload_to='docs/', blank=True, null=True)
driver_license_back = models.FileField(_('Driver License (Back Face)'), upload_to='docs/', blank=True, null=True)
is_approved = models.BooleanField(_('Is Approved'), default=False)
created_at = models.DateTimeField(auto_now_add=True)
@ -166,6 +170,55 @@ class Truck(models.Model):
return self.color_ar
return self.color
def save(self, *args, **kwargs):
# Compress images
if self.truck_picture:
self.truck_picture = self.compress_image(self.truck_picture)
# For docs, compress only if they are images
if self.registration_front:
self.registration_front = self.compress_image(self.registration_front)
if self.registration_back:
self.registration_back = self.compress_image(self.registration_back)
if self.driver_license_front:
self.driver_license_front = self.compress_image(self.driver_license_front)
if self.driver_license_back:
self.driver_license_back = self.compress_image(self.driver_license_back)
super().save(*args, **kwargs)
def compress_image(self, image_field):
if not image_field:
return image_field
try:
# Check file extension
ext = os.path.splitext(image_field.name)[1].lower()
if ext not in ['.jpg', '.jpeg', '.png', '.webp']:
return image_field
img = Image.open(image_field)
# If already small enough, don't compress (optional, but good for performance)
# if image_field.size < 300 * 1024: return image_field
if img.mode != 'RGB':
img = img.convert('RGB')
# Resize if too large
max_size = (1200, 1200)
img.thumbnail(max_size, Image.LANCZOS)
output = BytesIO()
img.save(output, format='JPEG', quality=70, optimize=True)
output.seek(0)
new_name = os.path.splitext(image_field.name)[0] + '.jpg'
return File(output, name=new_name)
except Exception as e:
# Not an image or other error, return as is
return image_field
class Shipment(models.Model):
STATUS_CHOICES = (
('OPEN', _('Open for Bids')),
@ -421,4 +474,4 @@ class Transaction(models.Model):
super().save(*args, **kwargs)
def __str__(self):
return f"{self.receipt_number} - {self.user.username} ({self.amount})"
return f"{self.receipt_number} - {self.user.username} ({self.amount})"

View File

@ -125,6 +125,7 @@
<hr class="my-4">
<h5>{% trans "Documents & Photos" %}</h5>
<p class="text-muted small">{% trans "Photos will be automatically resized for better performance. PDF files are accepted for documents." %}</p>
<div class="row {% if CURRENT_LANGUAGE == "ar" %}flex-row-reverse{% endif %}">
<div class="col-md-12 mb-3">
@ -144,7 +145,15 @@
<label class="form-label">{% trans "Driver License (Front Face)" %}</label>
{% if truck.driver_license_front %}
<div class="mb-2">
<img src="{{ truck.driver_license_front.url }}" class="img-thumbnail" style="height: 100px;">
{% with ext=truck.driver_license_front.name|lower %}
{% if ".pdf" in ext %}
<a href="{{ truck.driver_license_front.url }}" target="_blank" class="btn btn-outline-danger btn-sm">
<i class="fa fa-file-pdf me-1"></i> {% trans "View PDF" %}
</a>
{% else %}
<img src="{{ truck.driver_license_front.url }}" class="img-thumbnail" style="height: 100px;">
{% endif %}
{% endwith %}
</div>
{% endif %}
{{ form.driver_license_front }}
@ -154,7 +163,15 @@
<label class="form-label">{% trans "Driver License (Back Face)" %}</label>
{% if truck.driver_license_back %}
<div class="mb-2">
<img src="{{ truck.driver_license_back.url }}" class="img-thumbnail" style="height: 100px;">
{% with ext=truck.driver_license_back.name|lower %}
{% if ".pdf" in ext %}
<a href="{{ truck.driver_license_back.url }}" target="_blank" class="btn btn-outline-danger btn-sm">
<i class="fa fa-file-pdf me-1"></i> {% trans "View PDF" %}
</a>
{% else %}
<img src="{{ truck.driver_license_back.url }}" class="img-thumbnail" style="height: 100px;">
{% endif %}
{% endwith %}
</div>
{% endif %}
{{ form.driver_license_back }}
@ -167,7 +184,15 @@
<label class="form-label">{% trans "Registration (Front Face)" %}</label>
{% if truck.registration_front %}
<div class="mb-2">
<img src="{{ truck.registration_front.url }}" class="img-thumbnail" style="height: 100px;">
{% with ext=truck.registration_front.name|lower %}
{% if ".pdf" in ext %}
<a href="{{ truck.registration_front.url }}" target="_blank" class="btn btn-outline-danger btn-sm">
<i class="fa fa-file-pdf me-1"></i> {% trans "View PDF" %}
</a>
{% else %}
<img src="{{ truck.registration_front.url }}" class="img-thumbnail" style="height: 100px;">
{% endif %}
{% endwith %}
</div>
{% endif %}
{{ form.registration_front }}
@ -177,7 +202,15 @@
<label class="form-label">{% trans "Registration (Back Face)" %}</label>
{% if truck.registration_back %}
<div class="mb-2">
<img src="{{ truck.registration_back.url }}" class="img-thumbnail" style="height: 100px;">
{% with ext=truck.registration_back.name|lower %}
{% if ".pdf" in ext %}
<a href="{{ truck.registration_back.url }}" target="_blank" class="btn btn-outline-danger btn-sm">
<i class="fa fa-file-pdf me-1"></i> {% trans "View PDF" %}
</a>
{% else %}
<img src="{{ truck.registration_back.url }}" class="img-thumbnail" style="height: 100px;">
{% endif %}
{% endwith %}
</div>
{% endif %}
{{ form.registration_back }}
@ -198,4 +231,4 @@
</div>
</div>
</div>
{% endblock %}
{% endblock %}