pythondjangodjango-modelsdjango-modeladmindjango-model-field

Django relation of models


I have an e-commerce project and I stuck at admin view.

I have 2 models, namely Order and OrderItem. They are connected with FK relationship, and when Order is created I create both Order and related OrderItems in my admin page.

Orders in admin page: enter image description here

OrderItems in admin page: enter image description here

When I open my OrderItems, I see my OrderItem belongs to which Order. enter image description here

I want to add Order# to my OrderItem# list in my admin page.

In other words:

I want to express "OrderItem.str" = "existing OrderItem.str" + "Order.str"

My desired OrderItem__str__ format is something like:

OrderItem#4-Order#2

views.py file:

if request.user.is_authenticated:

    order = Order.objects.create(full_name=name, 
                                email=email, 
                                shipping_address=shipping_address, 
                                amount_paid=total_cost,
                                user=request.user)
    
    order_id = order.pk

    for item in cart:

        order_item = OrderItem.objects.create(order_id=order_id,
                                            product=item['product'], 
                                            quantity=item['qty'], 
                                            price=item['price'],
                                            user=request.user)
        
        
        # Update stock 

        product = Product.objects.get(title=item['product'])
        product.stock_qty -= int(item['qty'])
        product.save()

models.py file:

class Order(models.Model):

    full_name = models.CharField(max_length=300)

    email = models.EmailField(max_length=255)

    shipping_address = models.TextField(max_length=10000)

    amount_paid = models.DecimalField(max_digits=8, decimal_places=2)

    date_ordered = models.DateTimeField(auto_now_add=True)

    # Foreign key (FK)
    # Authenticated / not authenticated_users 
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)

    class Meta:

        # Update admin view label
        verbose_name_plural = 'Orders'

    # Admin list view of order records
    def __str__(self):
        return 'Order - #' + str(self.id)


class OrderItem(models.Model):

    # Link Order to Orderitem class
    # on_delete --> When Order is deleted, delete all order items
    # order_id is automatically created FK field
    order = models.ForeignKey(Order, on_delete=models.CASCADE, null=True)

    # on_delete --> When one of the product is deleted, delete related order items since product is not existing anymore
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)

    quantity = models.PositiveBigIntegerField(default=1)

    price = models.DecimalField(max_digits=8, decimal_places=2)

    # Foreign key (FK)
    # Authenticated / not authenticated_users 
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)

    # Get Order-id

    # Admin list view of order records
    def __str__(self):
        return 'Order Item - #' + str(self.id)

Solution

  • You can modify the __str__ method in the OrderItem model to include the order information. You can access the related order object through the foreign key order and retrieve the order id property. Check this code and update accordingly:

    class OrderItem(models.Model):
        # ... other fields ...
    
        def __str__(self):
            return 'OrderItem#' + str(self.id) + '-Order#' + str(self.order.id)
    

    Once you make this change, the OrderItem's string representation on the admin page will show the desired format as you wanted.