I have model and i have foreign key to another model and in that model i have company_name
and i'm looking for way to create custom_id with some letters and then add company name into that id
it should look like this:
123456GOOGLE
OR
123456AMAZON
I tried to use signals but thats not what i need so how can i solve that?
models.py
class CompanyUserPhysicalCard(models.Model):
card = models.ForeignKey(Cards, on_delete=models.CASCADE, related_name='company_physical_user_cards')
company = models.ForeignKey(Company, on_delete=models.SET_NULL, null=True, verbose_name='компания')
custom_id = models.CharField(max_length=7, unique=True, default=company_card_code, editable=False, null=True,
blank=True)
with that function i've got an error
'ForeignKey' object has no attribute 'company_name'
def company_card_code(company):
letters = '01234567890QLUBOK'
result_str = ''.join(random.choice(letters) for i in range(9)) + str(company.company_name)
return result_str
I would advise to calculate the name on-demand, like:
from random import choices
class CompanyUserPhysicalCard(models.Model):
def company_card_code(self):
letters = '01234567890QLUBOK'
return ''.join(choices(letters, k=6))
card = models.ForeignKey(
Cards,
on_delete=models.CASCADE,
related_name='company_physical_user_cards',
)
company = models.ForeignKey(
Company, on_delete=models.SET_NULL, null=True, verbose_name='компания'
)
_custom_id = models.CharField(
max_length=6, default=company_card_code, editable=False, blank=True
)
@property
def custom_id(self):
return f'{self._custom_id}{self.company.company_name}'
We thus generate the code prefix, and when we need it, we append the company name.
If the company later changes its name, for example 'Facebook'
to 'Meta'
, without having to alter the table, it will also change the custom_id
.
You can filter by concatenating with Concat
[Django-doc], for example:
from django.db.models.functions import Concat
CompanyUserPhysicalCard.objects.alias(
custom_id=Concat('_custom_id', 'company__company_name')
).filter(custom_id='123456GOOGLE')