Recover Custom Field when Editing Django Admin Form

Given the current models in models.py:

from django import forms
from django.db import models
from decimal import Decimal
from datetime import datetime, date

class Order (models.Model):
    assignment = models.ForeignKey("Assignment", on_delete=models.RESTRICT)
    qty = models.PositiveIntegerField(default=1)
    order_date = models.DateField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    
class Assignment (models.Model):
    assig_year = models.PositiveSmallIntegerField()
    customer = models.ForeignKey("Customer", on_delete=models.CASCADE)
    agent = models.ForeignKey("Agent", on_delete=models.CASCADE)
    
class Agent (models.Model):
    name = models.CharField(max_length=32)
    surname = models.CharField(max_length=32)
    
class Customer (models.Model):
    name = models.CharField(max_length=64)

I need to provide users with an admin custom form which allows to create and update orders in a more intuitive way. In order to do that, I exclude the assignment field (which bounds a Customer with a Sales Agent for a given year, but may not be so obvious to fill in for a user) and include a custom field for the user to select just a Customer instead. Based on this input and the order date, I internally look for the specific assignment that fulfills this criteria and assign it to the order to be stored in the Database. It looks like this:

admin.py

from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.contrib import admin
from django.db.models import CharField
from django import forms
from django.db import models
from .models import Customer, Assignment, Order

class OrderForm(forms.ModelForm):
    
    customers_list = forms.ModelChoiceField(queryset = Customer.objects.all())
    
    class Meta:
        model = Order
        exclude = (
            'assignment',
        )
    
    def save(self, commit=True):
        # Create an Order instance but do not commit to the DB yet
        obj: Order = super().save(commit=False)

        # Look for the associated assignment. If it doesn't exist, an error is raised
        try:
            assignment = Assignment.objects.get(assig_year=obj.order_date.year, customer=self.cleaned_data['customers_list'])
        except ObjectDoesNotExist:
            raise ValidationError('No assignment found')

        # Add the assignment reference to the order and save it
        obj.assignment = assignment
        obj.save()

        return obj
        
    def clean(self):
        cleaned_data = self.cleaned_data
                
        date_form = cleaned_data['order_date']
        customer_form = cleaned_data['customers_list']
        
        try:
            cleaned_data['assignment'] = Assignment.objects.get(assig_year=date_form.year, customer=customer_form.id)
        except ObjectDoesNotExist:
            raise ValidationError('No assignment found')
        
        # Then call the clean() method of the super class
        super(OrderForm, self).clean()

        # Finally, return the cleaned_data
        return cleaned_data

class OrderAdmin(admin.ModelAdmin):
    form = OrderForm
    
    fieldsets = (
      ('Order Data:', {
          'fields': ( 'customers_list', 'qty', 'order_date', 'price', )
      }),
    ) 

Everything works fine when creating a new order; however, if I enter into a previously created register in Admin mode, the Customer custom field is not automatically populated and I do not know how to recover its original value. Any ideas?

Вернуться на верх