Get the django object backward using foreign key - python

I have 3 models using Django Framework:
class Student(models.Model):
name = models.CharField()
surname = models.CharField()
class Group(models.Model):
groupId = models.AutoField()
name = models.CharField()
students = models.ForeignKey(Student)
class Faculty(models.Model):
facultyId = models.AutoField()
students = models.ForeignKey(Student)
I need to get the list of all students and for each one to have the student's group and faculty.

Well, first you need to modify your model relationships. With your current models, each Faculty and Group will have a single student.
You can modify the model to this:
class Group(models.Model):
groupId = models.AutoField()
name = models.CharField()
class Faculty(models.Model):
facultyId = models.AutoField()
class Student(models.Model):
name = models.CharField()
surname = models.CharField()
group = models.ForeignKey(Group)
faculty = models.ForeighKey(Faculty)
Then to get the Group and faculty of each student you can use select_related.
Now your query will look like this:
Students.objects.all().select_related('group', 'faculty')

class Student(models.Model):
name = models.CharField()
surname = models.CharField()
class Group(models.Model):
groupId = models.AutoField()
name = models.CharField()
students = models.ForeignKey(Student, related_name="group")
class Faculty(models.Model):
facultyId = models.AutoField()
students = models.ForeignKey(Student, "related_name"="faculty")
you can get this data Student.objects.filter(group__isnull=False, faculty__isnull=False )
It will return the student who have faculty and group.
for Json data:
class Student(serializer.ModelSerializer):
class Meta:
model = Student
fields = ('name', 'surname' , 'group', 'faculty')

Related

Dehydrate the same field django

I have a model Student:
class Student(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30, verbose_name='Name')
lastname = models.CharField(max_length=100, verbose_name='Lastname')
history = HistoricalRecords()
Also I have a model:
class Class(models.Model):
id = models.AutoField(primary_key=True)
student = models.models.ForeignKey(Student,on_delete = models.CASCADE, related_name='+')
my admin.py
class ClassResource(resources.ModelResource):
class Meta:
model = Class
fields = ('student',)
def dehydrate_student(self, Class):
student= getattr(Class.student, "name")
return '%s' % (student)
class ClassExportAdmin(ImportExportModelAdmin, ClassAdmin):
resource_class = ClassResource
admin.site.register(Class, ClassExportAdmin)
Now I am executing only name, is that possible to dehydrate the same field student one more time. I need past into my 2 column the surname of the student.
To export both Student.name and Student.lastname you can directly reference a Foreign Key relation in the fields parameter (docs):
class ClassResource(resources.ModelResource):
class Meta:
model = Class
fields = ('student__name', 'student__lastname')
This means that the column names will appear in your export as:
student__name
student__lastname
If you want the name to be different, you can directly declare a field:
name = Field(
column_name='name',
attribute='name',
widget=ForeignKeyWidget(Student, 'name'))
This will then appear in the export under name.

Adding multiple instances of a ForeignKey

I have a simple Person class and a Club class that should contain lots of Person instances:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=200)
class Club(models.Model):
name = models.CharField(max_length=200)
persons = models.ForeignKey(Person, on_delete=models.CASCADE)
How do I add more than one Person to the persons attribute? I want to build a database and then save it as follows:
club = Club(name='some_club')
club.person.add(Person(name='Alex'))
club.person.add(Person(name='John'))
club.save()
# etc. ...
Your foreign key is the wrong way round. To allow multiple people to be members of each club, the FK needs to be on Person pointing to Club.
class Person(models.Model):
name = models.CharField(max_length=200)
club = models.ForeignKey("Club", on_delete=models.CASCADE)
class Club(models.Model):
name = models.CharField(max_length=200)
...
some_club = Club(name='some_club')
some_club.save()
some_club.person_set.add(Person(name='Alex'))
some_club.person_set.add(Person(name='John'))
# Or:
Person.objects.create(name="Alex", club=some_club)
class Club(models.Model):
name = models.CharField(max_length=200)
class Person(models.Model):
name = models.CharField(max_length=200)
club = models.ForeignKey(Club, on_delete=models.CASCADE)
club1 = Club(name='some_club')
club1.save()
person1 = Person(name='Alex', club=club1)
person1.save()
person2 = Person(name='John', club=club1)
person2.save()
Edit: changed istance name to club1

Django convention for naming a ForeignKey that uses the to_field param?

I'm wondering if there is a convention for naming a foreign key field in Django that is mapped to another field with to_field. For example, should the Django field name be the model name and the database field name be the column name or is that confusing?
class Stations(models.Model):
name = models.CharField()
observations = models.ForeignKey(Observations,
to_field='zone_code'
db_column='zone_code')
class Observations(models.Model):
zone_code = models.IntegerField(unique=True)
metric_a = models.IntegerField()
metric_a = models.IntegerField()
It doesn't really make sense to have this:
class Stations(models.Model):
name = models.CharField()
observations = models.ForeignKey(Observations,
to_field='zone_code')
class Observations(models.Model):
zone_code = models.IntegerField(unique=True)
metric_a = models.IntegerField()
metric_a = models.IntegerField()
nor this
class Stations(models.Model):
name = models.CharField()
zone_code = models.ForeignKey(Observations,
to_field='zone_code')
class Observations(models.Model):
zone_code = models.IntegerField(unique=True)
metric_a = models.IntegerField()
metric_a = models.IntegerField()
because then you end up with observations_id or zone_code_id when the column in the database is actually the zone_code. Anyone have this issue before?

How to set Djangos through_field to an Intermediate model nested field

Is there any way I can set through_field to an intermediatory models's nested field,
Just for an example:
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('assignee__group', 'person'),
)
class GroupLeader(models.Model)
identity = models.ForeignKey(Person)
group = models.ForeignKey(Group)
#more fields
class Membership(models.Model):
assignee = models.ForeignKey(GroupLeader)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
# more fields
I tried doing it but I am getting an error:
The intermediary model 'Membership' has no field 'assignee__group'
NOTE: The above is just an example, just in case such a situation is encountered.
Your group leader should NOT be part of the M2M relation, this is just a metadata. So just add group into the Membership class.
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
)
class GroupLeaders(models.Model)
identity = models.ForeignKey(Person)
group = models.ForeignKey(Group)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
assignee = models.ForeignKey(GroupLeaders)
or you can even completely strip out the GroupLeaders class
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
leader = models.ForeignKey(Person, on_delete=models.CASCADE,
related_name="leading_memberships",
)

How to select all objects that are foreign keyed from another model in django?

Sorry for title, I do not know how else to express myself.
For example, I have this three models:
class Person(models.Model):
name = models.CharField()
class Teacher(models.Model):
person = models.ForeignKey(Person)
subject = models.CharField()
class Student(models.Model):
person = models.ForeignKey(Person)
grade = models.CharField()
How can I select all Person models that are Teachers?
Person.objects.filter(teacher__isnull=False)
# return Person who has a teacher pointing to it

Categories

Resources