Объект 'NoneType' не имеет атрибута 'customer_id'

У меня есть две модели в приложении под названием customer. Модели Customer и Account. Логика заключается в том, что у одного клиента может быть много счетов. Поэтому автоматически сгенерированный по умолчанию столбец 'id' в Customer является внешним ключом в Account. Account также имеет автоматически генерируемый по умолчанию столбец 'id'. Я создал функцию для поля account_id в Account, которое будет генерироваться по простому алгоритму. customer_id и id из Account будут конкатенированы как 'customer_id'_'id', (например, 1_1). Функция сначала проверит текущий customer_id созданного экземпляра Account, а затем проверит, какой последний id для этого customer_id. Для вновь добавленного счета будет захвачена часть id из account_id (т.е. часть после подчеркивания) и увеличена на 1. Затем произойдет конкатенация для тех же customer_id и id. Ниже приведен код:

models.py

from asyncio.windows_events import NULL
from django.db import models
from django.db.models.signals import pre_save
from django.contrib.auth.models import AbstractBaseUser
from .utils import set_account_id


class Customer(AbstractBaseUser):

    name = models.CharField(max_length=50)
    phone = models.BigIntegerField(null=True)
    email = models.EmailField(max_length=100, null=True)
    org_name = models.CharField(max_length=100, null = True)
    org_logo = models.ImageField(upload_to='logos', blank=True)
    subscription_start_date = models.DateField()
    subscription_end_date = models.DateField()
    password = models.CharField(max_length=50, blank=True, null=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'email']

    def __str__(self):
        return self.name


class Account(AbstractBaseUser):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    account_id = models.CharField(max_length=100, default=None, blank=True, null=True)
    name = models.CharField(max_length=50)
    phone = models.BigIntegerField(null=True)
    email = models.EmailField(max_length=100, null=True)  
    password = models.CharField(max_length=50, blank=True, null=True)
    account_type = models.CharField(max_length=50, choices=[
        ("survey", "SURVEY"), 
        ("sme", "SME"), 
        ("residents", "RESIDENTS")
        ])
    account_subscription_date = models.DateField(null=True)
    account_expiry_date = models.DateField(null=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'email']

    def __str__(self):
        return self.name 

def pre_save_set_account_id(sender, instance, *args, **kwargs):
    if not instance.account_id:
        instance.account_id = set_account_id(instance) #Error here
        print(instance.account_id)

pre_save.connect(pre_save_set_account_id, sender=Account)

utils.py

def set_account_id(instance):
    Klass = instance.__class__

    fk = 'customer_id'
    obj = Klass.objects.first()
    field_object = Klass._meta.get_field(fk)
    fk_value = field_object.value_from_object(obj) #Error here

    last_account = Klass.objects.filter(customer_id=fk_value).all().order_by('id').last()
    accounts_pk = last_account.id 
    new_account_int = accounts_pk + 1
    new_account_id = fk_value + '_' + new_account_int

    return new_account_id

Теперь, когда я ввел одну запись в >customer и пытаюсь ввести запись в account через панель администратора. Когда я заполняю форму для account в панели администратора, я оставляю account_id пустым. После нажатия на Save, я получаю следующую ошибку-:

AttributeError at /admin/customer/account/add/ Объект 'NoneType' не имеет атрибута 'customer_id'

Я закомментировал "Error here" в конкретных строках, в которых ошибка была указана отладчиком Django. Я новичок в Django и много чего перепробовал, но не смог устранить ошибку. Пожалуйста, помогите.

Эй, я не знаю, зачем вам вообще нужен этот account_id как поле db? Если он нужен вам для фильтрации, я предлагаю использовать сигнал post_save, например:

def post_save_set_account_id(sender, instance, *args, **kwargs):
    if instance.account_id is None:
        instance.account_id = f'{instance.customer.id}_{instance.id}'
        instance.save()

Но если вам не нужно строить sql запрос на основе поля account_id, я предлагаю использовать @property в модели Account:

@property
def account_id(self):
    return f'{self.id}_{self.account.id}'

тогда вы можете использовать его как поле модели, например:

account = Account.objects.get(pk=1)
account.account_id

печатает, например:

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