From fc35b28704a982d9d184bf0367d45fe72d8826c9 Mon Sep 17 00:00:00 2001 From: willy Date: Sun, 2 Mar 2025 10:43:19 +0100 Subject: [PATCH] Before 20250302 --- plant_catalog/catalog/admin.py | 32 +++++++++++++++++++++++++--- plant_catalog/catalog/models.py | 16 ++++++-------- plant_catalog/catalog/serializers.py | 23 +++++++++++--------- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/plant_catalog/catalog/admin.py b/plant_catalog/catalog/admin.py index 2696baa..750901c 100755 --- a/plant_catalog/catalog/admin.py +++ b/plant_catalog/catalog/admin.py @@ -1,7 +1,33 @@ from django.contrib import admin -from .models import Plant +from .models import Plant, PlantImage + +# Inline class for handling images +class PlantImageInline(admin.TabularInline): + model = PlantImage + extra = 3 # Display three empty forms for adding new images + fields = ('image',) # Only include fields that exist on PlantImage + + can_delete = True # Allow deletion of images + max_num = 10 # Limit to 10 images per plant (optional) @admin.register(Plant) class PlantAdmin(admin.ModelAdmin): - list_display = ('name', 'image') - search_fields = ('name',) + list_display = ('id', 'name', 'description', 'get_images', 'buy_price', 'sell_price', 'stock') + search_fields = ('name','description') # Add search functionality + inlines = [PlantImageInline] # Add inline editing for images + + def save_related(self, request, form, formsets, change): + super().save_related(request, form, formsets, change) + # Ensure all related PlantImage objects are saved correctly + for formset in formsets: + if hasattr(formset, 'save'): + formset.save() + + def get_images(self, obj): + """Display the first image or a placeholder in the list view.""" + images = obj.images.all() # Access related images via the 'images' related_name + if images.exists(): + return images[0].image.url # Show URL of the first image + return "No Images" + + get_images.short_description = "Images" # Header for the admin column diff --git a/plant_catalog/catalog/models.py b/plant_catalog/catalog/models.py index bc757ea..17af994 100755 --- a/plant_catalog/catalog/models.py +++ b/plant_catalog/catalog/models.py @@ -1,14 +1,12 @@ -# catalog/models.py - from django.db import models class Plant(models.Model): name = models.CharField(max_length=100) - description = models.TextField(null=True, blank=True) # Allow null and blank - image = models.ImageField(upload_to='plants/', null=True, blank=True) # Optional image - buy_price = models.FloatField(null=True, blank=True) # Allow null for buy price - sell_price = models.FloatField(null=True, blank=True) # Allow null for sell price - stock = models.IntegerField(default=0) # Default to 0 + description = models.TextField(null=True, blank=True) + buy_price = models.FloatField(null=True, blank=True) + sell_price = models.FloatField(null=True, blank=True) + stock = models.IntegerField(default=0) - def __str__(self): - return self.name +class PlantImage(models.Model): + plant = models.ForeignKey(Plant, related_name='images', on_delete=models.CASCADE) + image = models.ImageField(upload_to='plants/') diff --git a/plant_catalog/catalog/serializers.py b/plant_catalog/catalog/serializers.py index 20dfb76..47eddd7 100755 --- a/plant_catalog/catalog/serializers.py +++ b/plant_catalog/catalog/serializers.py @@ -1,17 +1,20 @@ -# catalog/serializers.py - from rest_framework import serializers -from .models import Plant +from .models import Plant, PlantImage + +class PlantImageSerializer(serializers.ModelSerializer): + class Meta: + model = PlantImage + fields = ['id', 'image'] # Fields to expose for each image + class PlantSerializer(serializers.ModelSerializer): + images = PlantImageSerializer(many=True, read_only=True) # Include related images + class Meta: model = Plant - fields = ['id', 'name', 'description', 'image', 'buy_price', 'sell_price', 'stock'] # Include all fields + fields = ['id', 'name', 'description', 'buy_price', 'sell_price', 'stock', 'images'] # Add the `images` field extra_kwargs = { - 'buy_price': {'required': False, 'allow_null': True}, # Allow null for buy price - 'sell_price': {'required': False, 'allow_null': True}, # Allow null for sell price - 'image': {'required': False, 'allow_null': True}, # Allow image to be optional - 'description': {'required': False, 'allow_null': True}, # Optional description + 'buy_price': {'required': False, 'allow_null': True}, + 'sell_price': {'required': False, 'allow_null': True}, + 'description': {'required': False, 'allow_null': True}, } - - \ No newline at end of file