Django order objects by specific related object field - python

In my project there is an Attraction model and an AttractionTag model related through a ForeignKey relationship. Every Attraction has the same set of AttractionTag, they differ only by the value field.
Now, I want to order Attractions based on the value field of a specific AttractionTag. For example, there is an AttractionTag named 'modern' for every attraction. I want to order Attractions based on modern AttractionTag value field.
I've tried
attractions.order_by('-attractiontag__value')
but this command order Attractions on AttractionTag in general, not based on a particular AttractionTag.
Here are the models
class Attraction (models.Model) :
city = models.ForeignKey(City, on_delete=models.CASCADE)
name=models.CharField(max_length=50, unique=True)
image = models.ImageField(upload_to=attractionImagePath, null=True, blank=False)
imageTop = models.ImageField(upload_to=attractionTopImagePath, null=True, blank=True)
pub_date = models.DateTimeField(auto_now_add=True)
class AttractionTag (models.Model):
attraction=models.ForeignKey(Attraction, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
value=models.IntegerField(default=0)
How can I solve?
Thank you

Ok, I found a solution.
tags = AttractionTag.objects.filter(attraction__city=city)
tags = tags.filter(name='modern').order_by('-value')
attraction = [tag.attraction for tag in tags]
Should work

Related

Django - Filter by multiple values (Logical AND) on ManyToMany field

I'm trying to build job-candidate match system.
I want to filter Candidates by Critical Skills needed for the Job.
Every candidate has multiple skills.
Every Job has multiple 'required' JobSkill which is a model that also contains importance of the skill.
I want to filter my candidates and to get only candidates how have all the critical skills required for a job.
A critical skill is defined as a JobSkill with importance = 3.
For a given job 'job_1' I want to get the relevant candidates as follows:
critical_skills = job_1.required_skills.filter(importance=3)
relevant_candidates = Candidate.objects.filter('candidate how has all the critical_skills)
models.py:
class Skill(models.Model):
title = models.CharField(max_length=100, blank=False, unique=True)
class JobSkill(models.Model):
skill = models.ForeignKey(Skill, on_delete=models.CASCADE)
class Importance(models.IntegerChoices):
HIGH = 3
MEDIUM = 2
LOW = 1
importance = models.IntegerField(choices=Importance.choices)
class Job(models.Model):
title = models.CharField(max_length=100, null=False)
required_skills = models.ManyToManyField(JobSkill, blank=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
class Candidate(models.Model):
title = models.CharField(max_length=100, blank=False, null=False)
full_name = models.CharField(max_length=100, blank=False, null=False)
skills = models.ManyToManyField(Skill, blank=True)
I would appreciate any help with this!!
Thank you
You can simply chain the filters as per Spanning multi-valued relationships, when spanning multi-valued relationships in a filter we restrict the related model with each filter. So you can do as follows:
relevant_candidates = Candidate.objects.all()
for job_skill in critical_skills:
relevant_candidates = result.filter(skills__id=job_skill.skill_id)
Note: As the amount of critical skills would increase this would make more and more joins causing the query to grow more complicated
and the results would be quite slow.
Note: Instead of having a ManyToManyField with the table JobSkill which only has a foreign key to Skill and a field
importance you should simply have a ManyToManyField with Skill
and have a custom through model that would have a foreign key to both
Job and Skill and the field importance. See Extra fields on
many-to-many
relationships

ForeignKey to specific queryset django

Is there a way to refer to specific object of Model? Suppose I have some models like below:
# models.py
class VehicleCategoryCode(models.Model):
category = models.CharField(max_length=5)
name = models.CharField(max_length=20)
class Code(models.Model):
category = models.ForeignKey(VehicleCategoryCode, on_delete=models.CASCADE)
index = models.CharField(max_length=4, blank=True)
label = models.CharField(max_length=50)
order = models.CharField(max_length=20, blank=True)
is_active = models.BooleanField(default=True)
# pay attention to the Model
class Vehicle(models.Model):
label = models.CharField(max_length=80)
model = models.CharField(max_length=30)
Currently Vehicle is not linked to any model.
Now Code model is ForeignKey to VehicleCategoryCode, which has two objects. In the VehicleCategoryCode the first object label (for convenience sake) will be referenced by Vehicle.label, and the second object model (once again for convenience) will be referenced by Vehicle.model. So each field in Vehicle can refer to the same model, but different objects.
So basically I'm wondering if something like the pseudo code below can be achieved anyhow.
class Vehicle(models.Model):
label = models.ForeignKey(VehicleCategoryCode__name='label', on_delete=models.CASCADE)
model = models.ForeignKey(VehicleCategoryCOde__name='model', on_delete=models.CASCADE)
Any suggestion or advice would be appreciated. Thank you.
You can make use of the limit_choices_to=… parameter [Django-doc]:
Vehicle(models.Model):
label = models.ForeignKey(
Code,
limit_choices_to={'category__name': 'label'},
on_delete=models.CASCADE
)
model = models.ForeignKey(
Code,
limit_choices_to={'category__name': 'model'},
on_delete=models.CASCADE
)
For ModelForms and in the ModelAdmin it will limit the choices, note however that tese are not enforced by the database.

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)

Filter by presence in a model's set

I have a Customer model that has many Locations, i.e., there is a location_set attribute on the model that returns a list of locations. Each Location also has many customers, i.e., a customer_set attribute.
I have one customer instance with all of its corresponding attributes. What I want to do is return all other customers who are present in at least of the locations in the customer's location_set. Is there a clean way to do this without having to manually manipulate the queryset and make a ton of calls to the DB?
class Customer(AbstractUser):
current_location = models.ForeignKey('device.Location',
null=True, blank=True, related_name='customers_present')
default_location = models.ForeignKey('device.Location',
null=True, blank=True, related_name='default_customers')
class Location(models.Model):
name = models.CharField(max_length=50, help_text="The name of the location")
customers = models.ManyToManyField(settings.AUTH_USER_MODEL,
through='customer.Membership')
class Membership(models.Model):
customer = models.ForeignKey(Customer)
location = models.ForeignKey('device.Location')
date_joined = models.DateTimeField(auto_now_add=True)
Without your model definitions it is very difficult to provide an exact answer to your question, something like the below could work:
Customer.objects.filter(location__in=your_customer_instance.location_set.all()).exclude(pk=your_customer_instance.pk)

Categories

Resources