Reputation:
I have two model called organization and staff.Staff model have onetoone relation with user and Foreignkey relation to the organization.The problem what i got is to filter the staffs by their related organization.I have tried liked this but didn't worked out.
models.py
class Staff(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user')
name = models.CharField(max_length=255, blank=True, null=True)
organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, blank=True, null=True,
related_name='organization')
.....other fields.....
views.py
def view_staff_users(request):
staff_users = User.objects.filter(is_staff=True)
organizations = Organization.objects.all()
staffs_by_org = Staff.objects.select_related('organization')
# tried this also:
# staffs_by_org = []
# print('staffff',staffs_by_org)
# for organization in organizations:
# staffs = Staff.objects.filter(organization=organization)
# staffs_by_org.extend(staffs)
# print('staaa',staffs_by_org)
Edited views:
def view_staff_users(request):
staff_users = User.objects.filter(is_staff=True)
organizations = Organization.objects.all()
staffs_by_org = []
for organization in organizations:
staffs_by_org = Staff.objects.filter(organization__name=organization).select_related('organization')
template
{% for user in staffs_by_org %}
# tried this also: {% for u in user.organization_set.all %}
{{user.user.name}}
{{user.username}}
{{user.email}}
{{user.user.organization}}
{% endfor %}
Edit: My template looks like this.
<ul class="nav nav-tabs customtab" role="tablist">
<li class="nav-item"> <a class="nav-link active" data-toggle="tab" href="#all" role="tab"><span class="hidden-sm-up"></span> <span class="hidden-xs-down">All Staffs</span></a> </li>
{% for organization in organizations %}
<li class="nav-item"> <a class="nav-link" data-toggle="tab" href="#{{organization.name}}" role="tab"><span class="hidden-sm-up"></span> <span class="hidden-xs-down">{{organization.name}}</span></a> </li>
{% endfor %}
</ul>
<div class="tab-content">
<div class="tab-pane active" id="all" role="tabpanel">
{% for user in staff_users %}
{{user.user.name}}
{{user.username}}
{{user.email}}
{{user.user.organization}}
{% endfor %}
</div>
{% for organization in organizations %}
<div class="tab-pane tab" id="{{organization.name}}" role="tabpanel">
{% endfor %}
{% for user in staffs_by_org %}
# tried this also: {% for u in user.organization_set.all %}
{{user.user.name}}
{{user.username}}
{{user.email}}
{{user.user.organization}}
{% endfor %}
</div>
Upvotes: 1
Views: 560
Reputation: 696
I think one problem is that you created a loop that is rewriting itself instead of appending each batch of staff users to your queryset.
One way to do what you want (return all staff that belong to a set of organizations) is to use the in
filter operator.
So, in your views.py
:
organizations = Organization.objects.all()
staffs_by_org = Staff.objects.filter(
organization__in=organizations).select_related('organization')
This will return all staff from whatever organizations
is.
If you want a dynamic filter for the organization name, then what you have to do is:
organizations
variable
from objects.all()
to objects.filter(URL_PARAMETER)
Then staffs_by_org
will only return the staff from that organization.
Upvotes: 0
Reputation: 477035
You can filter for example with:
staffs_by_org = Staff.objects.filter(
organization__name='My organization'
).select_related('organization')
The staffs_by_org
is a QuerySet
of Staff
s. I therefore stronly advice to use staff
in the iterator. You can access the organization with staff.organization
:
{% for staff in staffs_by_org %}
{{ staff.name }}
{{ staff.user.username }}
{{ staff.user.email }}
{{ staff.organization }}
{% endfor %}
If the organization has for example a name
, you can render it with:
{% for staff in staffs_by_org %}
{{ staff.name }}
{{ staff.user.username }}
{{ staff.user.email }}
{{ staff.organization.name }}
{% endfor %}
Note that the related_name
of a ForeignKey
is the name of the relation in reverse. A better name is probably 'staff'
. If you refer to the user model, it is better to use get_user_model()
[Django-doc], since if you later change your mind, you can easily use another user model.
from django.contrib.auth import get_user_model
class Staff(models.Model):
user = models.OneToOneField(
get_user_model(),
on_delete=models.CASCADE,
related_name='staff'
)
name = models.CharField(max_length=255, blank=True, null=True)
organization = models.ForeignKey(
Organization,
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name='staff'
)
Upvotes: 1