changing image size in truck reg
This commit is contained in:
parent
c5c799b7d6
commit
d8b540ccd4
Binary file not shown.
Binary file not shown.
@ -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')
|
||||
@ -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)'),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@ -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})"
|
||||
@ -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 %}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user