Foreign Key relationship at second level - python

Suppose I have three models such as -
class company(models.Model):
companyName = models.charField()
class branch(models.Model):
branchName = models.charField()
company = models.ForeignKey(company, on_delete=models.CASCADE)
Now in the third model, that is customer I want to have unique customer per compnay so I did -
class customers(models.Model):
customerName = models.charField()
branch= models.ForeignKey(branch, on_delete=models.CASCADE)
company = models.ForeignKey(company, on_delete=models.CASCADE)
class Meta:
unique_together = (
('company', 'customerName'),
)
Now since the branch has already got company as a foreign field and I'm again using both branch and company in the customers model, will this form a cyclic structure, or is this a wrong way of doing it?
And if I remove the company from the customers model because branch already has company as a foreign field, how can I set unique customers per company at the database level?

This shouldn't create a cyclical structure, but you don't need company as an attribute.
You can access company through the branch foreign key. This should work:
class customers(models.Model):
customerName = models.charField()
branch= models.ForeignKey(branch, on_delete=models.CASCADE)
class Meta:
unique_together = (
('branch__company', 'customerName'),
)
Although, branch and customerName should theoretically be unique_together as well.

Related

Django- How to replace list of items of a related set

I have table Group and UserConfig
A group has many users, each user in a group has a config item
UserConfig: unique (group_id, user_id)
Example:
class Group(models.Model):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=255, unique=True)
class UserConfig(models.Model):
id = models.BigAutoField(primary_key=True)
group = models.ForeignKey(Group, on_delete=models.CASCADE, related_name='user_configs')
user_id = models.IntegerField()
config = models.JSONField()
I want to replace all UserConfig instances of a group (update existing rows, add new rows and remove which rows are not in the new list)
# list_replace_configs: List[UserConfig]
group.user_configs.set(list_replace_configs, bulk=False, clear=False)
This method not working because it uses method remove()
remove(*objs, bulk=True): only exists if ForeignKey field has null=True
if ForeignKey field has null=True: it does not removed UserConfig object, but just set user_config.group = None
I don't understand why django designs this method.
How to replace all UserConfig instances of a group ?
I recommend using constraints in class Meta:
(In Django id in generate auto and you don't need to add it as a field)
class Group(models.Model):
name = models.CharField(max_length=255, unique=True)
class UserConfig(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE, related_name='user_configs')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_configs')
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'group',],
name='unique_user_config')
]

Foreign keys and serializers in django rest

class Patient(models.Model):
user = models.OneToOneField(User, related_name='patient', on_delete=models.CASCADE)
id_type = models.CharField(max_length=300)
id_number = models.CharField(max_length=300)
creation_date = models.DateField(default=datetime.date.today)
class Allergie(models.Model):
name = models.CharField(max_length=300, default="X")
class PatientAllergies(models.Model):
patient = models.ForeignKey(Patient, related_name="patient_allergies", on_delete=models.CASCADE)
allergie = models.ForeignKey(Allergie, on_delete=models.CASCADE, null=True)
professional_contract = models.ForeignKey(ProfessionalContract, null=True ,on_delete=models.CASCADE)
Is it possible to retrieve a patient objecto with a property that is a list of all his allergies, including name and id with these models?
you have the PatientAllergies as a chain,
so
patientAllergies = PatientAllergies.objects.get(patient.id_number='0000')
patientAllergies.allergie #you get the single allergie model connect with it, take care it is a foreignKey so it is singolar and not many
patientAlleriges.patient.user #will give you access to all the data of the user
You can achieve this with prefetch_related and Prefetch like so:
Patient.objects.prefetch_related(
Prefetch('patient_allergies__allergie', to_attr='allergies')
)
EDIT: Just learned that to_attr will not work on multiple levels of prefetch. Another approach I can think of is use a model property for Patient that returns its related allergies like this:
class Patient(models.Model):
#property
def allergies(self):
return Allergie.objects.filter(patientallergies_set__patient=self)
Then in your serializer, the allergies field can use the Allergies serializer

Django - limit choices to foreign key

I have the following model in Django
class Transfer(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, limit_choices_to={'is_accepted':True})
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I would like to filter the users based on is_accepted field. The problem is, that this field is declared in a model called Employee, which is in onetoone relationship with user.
Is there any possibility to reach Employee fields and filter them in this manner?
You can normally define a filter like:
class Transfer(models.Model):
user = models.ForeignKey(
User,
on_delete=models.PROTECT,
limit_choices_to={'employee__is_accepted': True}
)
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)

django model field depend on the value of another field

The use case of my application is I will have various fields to fill and among them one is Industry field and another is Segment Field for brand. The industry field is like category that brand falls into. So, if i choose the industry as Health Care for XYZ brand then the segment field should show the items like 'Ayurveda', 'Dental Clinics' (all health care related items). Basically, its like sub-category.
Here is a sample model
class Industry(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Meta:
verbose_name = 'Industry'
verbose_name_plural = 'Industries'
def __str__(self):
return self.name
class Segment(models.Model):
industry = models.ForeignKey(Industry, related_name='segment', on_delete=models.CASCADE)
name = models.CharField(max_length=150, blank=True, null=True)
class Meta:
verbose_name = 'Segment'
verbose_name_plural = 'Segments'
def __str__(self):
return f'{self.industry.name} - {self.name}'
class BusinessModel(models):
industry = models.ForeignKey(Industry, blank=False, null=False, related_name='industry', on_delete=models.CASCADE)
# segements = models.ForeignKey()
total_investment = models.CharField() # will be choice field
This is a simple model and I have not created Segment model as I am not sure how to approach to this problem. I am just curios to know, if for such case, do i have to something special in models.py or in the view side. Such type of things get arise during development phase, thus, I want to be clear on problem solving pattern in django.
UPDATE
https://www.franchisebazar.com/franchisor-registration here if you choose industry inside Business model section, the segment will be updated accordingly.
You can have a 3 model design like
class Industry(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Segment(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Mapping(models.Model):
industry = models.ForeignKey(Industry)
segment = models.ForeignKey(Segment)
You need to define relations between your models. You can find documentation about ManyToMany relation here which is suitable in your case.
you can use ChainedForeginKey.. Check the below links
customizing admin of django to have dependent select fields
https://django-smart-selects.readthedocs.io/en/latest/installation.html

How to Save multiselect in django model?

I have two model Business and Category. I want to save Multiple categories in Business.
class Business(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
business_name = models.CharField(max_length=100)
category = models.IntegerField()
keyword = models.CharField(max_length=100)
and Category Model Is Here
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.CharField(max_length=100)
Category Model is already filled with values.
you have two option for that 1) many to one, 2) many to many
1) many to one is ForeignKey to add in category model and link each category with business, in this you can identify which category is child of buisness, you can find more details in django document
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.CharField(max_length=100)
business = models.ForeignKey(Business, on_delete=models.CASCADE)
2) many to many is select multiple category in business, and you can access all thing in business model and in you write query on business model and access to also category for that you need write category before buisness, you can find more detail in django document
class Business(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
business_name = models.CharField(max_length=100)
category = models.IntegerField()
keyword = models.CharField(max_length=100)
category= models.ManyToManyField(Category)

Categories

Resources