Django query using ManytoManyField - django

Using example code:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
How could I get the name of the last 5 persons and their group's name order by date_joined? Something like:
"name1" "group1" "19/02/2019"
"name2" "group1" "19/02/2019"
"name1" "group2" "19/02/2019"
"name3" "group1" "18/02/2019"
"name4" "group2" "17/02/2019"
I have tried many options but I am not able to do it :S Thanks in advance.

You can get this by following
Membership.objects.values('person__name', 'group__name', 'date_joined').order_by(date_joined)[:5]

Related

Django find common instances data in two models

I have models like:
class Hospital(models.Model):
name = models.CharField(max_length=200, unique=True)
manager_name = models.CharField(max_length=200, default='')
manager_id = models.CharField(max_length=200)
def __str__(self):
return f'{self.name}'
class Sick(models.Model):
name = models.CharField(max_length=200, default='')
nationalID = models.CharField(max_length=200)
illName = models.CharField(max_length=200)
hospital = models.ForeignKey(Hospital, related_name='sicks', on_delete=models.DO_NOTHING)
def __str__(self):
return f'({self.name}, {self.nationalID})'
class Employee(models.Model):
name = models.CharField(max_length=200, default='')
nationalID = models.CharField(max_length=200)
company = models.ForeignKey(Company, related_name='employees', on_delete=models.CASCADE)
def __str__(self):
return f'({self.name}, {self.nationalID})'
views:
#api_view(['POST'])
def get_sick_employee_by_hospital(request):
pass
and a serializer like :
from rest_framework import serializers
class NameSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=200, allow_null=False)
my problem is :
my view get_sick_employee_by_hospital() receives a hospital name and it must return all sick peoples that are employees and They have visited that hospital, in a dictionary with keys 1,2,3,..., n and values like "(name, nationalID)".
Pay attention that it does not matter which value is assigned to which key.
What is the best way to do that ? how can i get all sick peoples that are employees and They have visited a hospital?

How to show foreign key field value instead of id in Django admin?

class Country(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100)
class Info(models.Model)
country_name = models.ForeignKey(Country, on_delete=models.CASCADE)
country_code = models.ForeignKey(Country, on_delete=models.CASCADE)
info = models.CharField(max_length=100)
In admin interface, while adding object in 'Info' model, 'country_name' field show IDs of countries by default. But I want to show names of countries instead of IDs.
And similarly, 'country_code' field of 'Info' model also show IDs of countries by default. But I want to show codes of countries instead of IDs.
How to do this?
Try this way:
The value you will return from __str__ that would be shown in admin.
class Country(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100)
def __str__(self):
return self.name
class Info(models.Model)
country_name = models.ForeignKey(Country, on_delete=models.CASCADE)
country_code = models.ForeignKey(Country, on_delete=models.CASCADE)
info = models.CharField(max_length=100)
def __str__(self):
return str(self.country_name.name)
Why are you using 2 fields for same result? Your model of Info should be:
class Info(models.Model)
country_name = models.ForeignKey(Country, on_delete=models.CASCADE)
info = models.CharField(max_length=100)
def __str__(self):
return str(self.country_name.code)

Django many to many field add with through model fields

I have the models below, and I want to add a member to a group in a view. How could I do this, also adding the date_joined and invite_reason correctly. I am using forms without the generics views.
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
To create the reltationship you have to base your form on the relationship model:
class MembershipForm(ModelForm):
class Meta:
fields = ['person', 'group', 'date_joined']
model = Membership
This form will be composed of a select for the persons, a select for the group and a datefield for the date_joined

Get associative table data from 2 level depths relationship in django using foreign keys

This is my problem that im trying to figure out being a beginner with django
I want to get the country in user app knowing that city table is connected to country table using foreign key. User table has city_id column. Please note that user already logged in. I get the city already but not the country
After that in my instructor app, i get that currency which is connected to country column currency_id.
This is what i have.
/instructors/model.py
from django.db import models
from locations.models import City, Country
class Class(models.Model):
...
city = models.ForeignKey(City, null=True, blank=True)
class Currency(models.Model):
name = models.CharField(max_length=20)
symbol = models.CharField(max_length=7, help_text="Code HTML")
initials = models.CharField(max_length=5, help_text="e.g. : CLP (Chilean Pesos)")
class Meta:
verbose_name_plural = "currencies"
def __unicode__(self):
return self.name
def get_label(self):
return '%s (%s)' % (self.symbol, self.initials)
/users/model.py
class User(AbstractUser):
...
city = models.ForeignKey(City, blank=True, null=True, db_index=True)
...
def get_locality(self):
locality = ''
if self.location:
locality = '%s, %s, %s' % (self.location.name, self.location.city.name, self.city.country.name)
elif self.city:
locality = '%s, %s' % (self.city.name, self.city.country.name)
return locality
/locations/model.py
from django.db import models
class Country(models.Model):
code = models.CharField(max_length=3)
name = models.CharField(max_length=100)
order = models.IntegerField(default=0)
currency_id = models.IntegerField(max_length=3)
class Meta:
verbose_name_plural = "countries"
def __unicode__(self):
return self.name
class City(models.Model):
country = models.ForeignKey(Country)
name = models.CharField(max_length=100)
order = models.IntegerField(default=0)
class Meta:
verbose_name_plural = "cities"
def __unicode__(self):
return "%s, %s" % (self.name, self.country)
class Location(models.Model):
city = models.ForeignKey(City)
name = models.CharField(max_length=100)
class Meta:
verbose_name_plural = "locations"
def __unicode__(self):
return "%s, %s" % (self.name, self.city)

Access intermediary model values Django

I have a simple question. using the example from django above. How can i get for example the invite_reason from Person on a Group ? or all joined dates to all groups from that person ? thanks.
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
You'll need to query your Membership model for that, like so:
memberships = Membership.objects.filter(person=person, group=group)
for membership in memberships:
membership.invite_reason
Alternately, you could query it based on the relation:
memberships = person.membership_set.filter(group=group)
for membership in memberships:
membership.invite_reason