Reputation: 14824
If have a model for companies. These companies have an attribute employment_set
, because workers are assigned to companies via the employment relation. How can I query all employees for a given company?
The model for the employements look like this:
class Employment(
SoftDeletableModel,
TimeStampedModel,
models.Model
):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
employee = models.ForeignKey(UserWorkerProfile)
employed_by = models.ForeignKey(UserOwnerProfile)
I tried using company.employment_set.values("employee")
, but this returns a strange activatorquery set. Is there a way to return the normal queryset? Or is values()
already the correct method?
Edit: To eloborate a little more: I want to end up with a queryset containing all the UserWorkerprofile model instances.
In the documentation for values()
it says:
Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable.
and I want exactly a queryset of model instances.
Upvotes: 2
Views: 2067
Reputation: 477794
Based on your comment, you want all UserWorkerProfile
s that have a (there can be zero, one or more) related Employment
instances an Employment
instance that has as Company
(every Employment
has exactly one company
), a given company.
We can query such UserWorkingProfile
s with the following query:
UserWorkingProfile.objects.filter(employment__company=some_comany)
So this queryset will return all UserWorkingProfile
s for which there exists an Employment
instance that links to the given company some_company
and that UserWorkingProfile
.
In Django one uses two consecutive underscores to look "through" a relation (this can be used in bidirectionally, note that two consecitive underscores are used for other things than looking through relations).
We thus wrote a query that looks, more or less like:
SELECT `userworkingprofile`.*
FROM `userworkingprofile`
JOIN `employment` ON `employment`.`employee_id` = `userworkingprofile`.`id`
WHERE `employment`.`company_id` = 123
With 123
in reality the pk
of some_company
.
Note that it is possible that the same UserWorkingProfile
occurs multiple times in this queryset, if the employee has worked several times for some_company
.
If you want every UserWorkingProfile
to occur at most once, you should add .distinct()
to it:
UserWorkingProfile.objects.filter(employment__company=some_comany).distinct()
Although Django indeed defines a object manager named employment_set
on a Company
instance, as far as I know you can not "combine" two such managers (so
will not work).some_company.employment_set.employee
Upvotes: 2