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.translation import gettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.utils.html import format_html 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 .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner, HomeSection
from .whatsapp import send_whatsapp_message from .whatsapp import send_whatsapp_message
@ -38,7 +39,14 @@ class ProfileAdmin(admin.ModelAdmin):
if obj.is_expired(): if obj.is_expired():
return format_html('<span style="color: red; font-weight: bold;">{}</span>', _('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: if days <= 7:
return format_html('<span style="color: orange; font-weight: bold;">{} ({} {})</span>', _('Expiring soon'), days, _('days')) 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) @admin.register(Truck)
class TruckAdmin(admin.ModelAdmin): 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') search_fields = ('plate_no', 'owner__username', 'model')
list_filter = ('truck_type_link', 'is_approved') 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) @admin.register(Shipment)
class ShipmentAdmin(admin.ModelAdmin): class ShipmentAdmin(admin.ModelAdmin):

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 gettext_lazy as _
from django.utils.translation import get_language from django.utils.translation import get_language
from django.utils import timezone from django.utils import timezone
from django.core.files import File
import random import random
import string import string
import os
from io import BytesIO
from PIL import Image
class Country(models.Model): class Country(models.Model):
name = models.CharField(_('Country Name'), max_length=100) name = models.CharField(_('Country Name'), max_length=100)
@ -127,10 +131,10 @@ class Truck(models.Model):
# Pictures # Pictures
truck_picture = models.ImageField(_('Truck Picture'), upload_to='trucks/', blank=True, null=True) 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_front = models.FileField(_('Registration (Front Face)'), upload_to='docs/', blank=True, null=True)
registration_back = models.ImageField(_('Registration (Back 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.ImageField(_('Driver License (Front 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.ImageField(_('Driver License (Back 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) is_approved = models.BooleanField(_('Is Approved'), default=False)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
@ -166,6 +170,55 @@ class Truck(models.Model):
return self.color_ar return self.color_ar
return self.color 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): class Shipment(models.Model):
STATUS_CHOICES = ( STATUS_CHOICES = (
('OPEN', _('Open for Bids')), ('OPEN', _('Open for Bids')),

View File

@ -125,6 +125,7 @@
<hr class="my-4"> <hr class="my-4">
<h5>{% trans "Documents & Photos" %}</h5> <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="row {% if CURRENT_LANGUAGE == "ar" %}flex-row-reverse{% endif %}">
<div class="col-md-12 mb-3"> <div class="col-md-12 mb-3">
@ -144,7 +145,15 @@
<label class="form-label">{% trans "Driver License (Front Face)" %}</label> <label class="form-label">{% trans "Driver License (Front Face)" %}</label>
{% if truck.driver_license_front %} {% if truck.driver_license_front %}
<div class="mb-2"> <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> </div>
{% endif %} {% endif %}
{{ form.driver_license_front }} {{ form.driver_license_front }}
@ -154,7 +163,15 @@
<label class="form-label">{% trans "Driver License (Back Face)" %}</label> <label class="form-label">{% trans "Driver License (Back Face)" %}</label>
{% if truck.driver_license_back %} {% if truck.driver_license_back %}
<div class="mb-2"> <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> </div>
{% endif %} {% endif %}
{{ form.driver_license_back }} {{ form.driver_license_back }}
@ -167,7 +184,15 @@
<label class="form-label">{% trans "Registration (Front Face)" %}</label> <label class="form-label">{% trans "Registration (Front Face)" %}</label>
{% if truck.registration_front %} {% if truck.registration_front %}
<div class="mb-2"> <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> </div>
{% endif %} {% endif %}
{{ form.registration_front }} {{ form.registration_front }}
@ -177,7 +202,15 @@
<label class="form-label">{% trans "Registration (Back Face)" %}</label> <label class="form-label">{% trans "Registration (Back Face)" %}</label>
{% if truck.registration_back %} {% if truck.registration_back %}
<div class="mb-2"> <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> </div>
{% endif %} {% endif %}
{{ form.registration_back }} {{ form.registration_back }}