There are three models Person, Author and Singer.
class Person(models.Model):
name = models.CharField(max_length=256, null=True)
class Meta:
db_table = "Person"
class Author(models.Model):
person = models.ForeignKey(Person)
rating = models.InegerField(null=True)
class Meta:
db_table = "Author"
class Singer(models.Model):
person = models.ForeignKey(Person)
rating = models.IntegerField(null=True)
class Meta:
db_table = "Singer"
I have to perform joining between Author and Singer in ORM
MySQL will be like
select S.* from Singer as S join Author as A on S.person_id=P.person_id;
The simpler solution according to your database model would be
author_objects = Author.objects.filter(person=singer_object.person) # where singer_object
# now do something with the author_objects
Related
I want to count the no of movies worked by the actors in api. i have tried this but not working
models.py
class Actor(models.Model):
actors = models.CharField(max_length=100)
class Genre(models.Model):
genre = models.CharField(max_length=100)
class Movie(models.Model):
name = models.CharField(max_length=100)
actors = models.ManyToManyField(Actor, related_name="actor_movies")
genre = models.ManyToManyField(Genre,related_name="genre_movies")
serializers.py
class ActorSerializer(serializers.HyperlinkedModelSerializer):
actor_movies = serializers.RelatedField(source='actor.movies', read_only = True)
class Meta:
model = Actor
fields = ['id','actors','actor_movies']
class GenreSerializer(serializers.HyperlinkedModelSerializer):
genre_movies = serializers.RelatedField(source='genre.names', read_only = True)
class Meta:
model = Genre
fields = ['id','genre','genre_movies']
class MovieSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Movie
fields = ['url','name','actors','genre']
im getting output like this
[
{
"id": 1,
"genre": "Ajith"
},
{
"id": 2,
"genre": "Vijay"
}
]
in actual output i need the total no of movies he worked also.
You can use a SerializerMethodField:
class ActorSerializer(serializers.HyperlinkedModelSerializer):
count_actor_movies= serializers.SerializerMethodField()
def get_count_actor_movies(self, instance):
return instance.actor_movies.count()
class Meta:
model = Actor
fields = ['id','actors','count_actor_movies']
For more details, the official docs are here.
In serializer, class I am trying to get the category details such as "name" but the following code gives me the foreignkey id
models.py
class Category(MP_Node, Timestamps):
name = models.CharField(_('Name'), max_length=255, db_index=True)
class VideoCategory(Category):
image = models.ImageField(upload_to='video_categories', blank=True, null=True, max_length=255)
class VideoCategoryVideo(BaseModel, Timestamps, SoftDelete):
video = models.ForeignKey(Video, on_delete=models.CASCADE)
category = models.ForeignKey(VideoCategory, on_delete=models.CASCADE, null=True)
serializers.py
class VideoCategoryVideoSerializer(serializers.ModelSerializer):
class Meta:
model = VideoCategoryVideo
fields = ('category', )
class VideosDetailsListSerializer(serializers.ModelSerializer):
category = serializers.SerializerMethodField()
class Meta:
model = Video
fields = ('id', 'create_date', 'category')
def get_category(self, data):
cate = VideoCategoryVideo.objects.filter(video=data.id)
category = VideoCategoryVideoSerializer(cate, many=True)
return category.data
result is:
"category": [
{
"category": 1
}]
but the expected result is
"category": [
{
"name": "cate_name"
}]
You can add a CharField to VideoCategoryVideoSerializer and specify the source of the value like this:
class VideoCategoryVideoSerializer(serializers.ModelSerializer):
name = serializers.CharField(source='category.name', read_only=True)
class Meta:
model = VideoCategoryVideo
fields = ('category', 'name')
This will tell the serializer to get the value for name from the related category.
Hello, I am starting to learn Django Rest Framework, i have come across a problem, that i couldn't solve, that is described below:
I have defined three models in models.py:
Endpoint Model
class Endpoint(models.Model):
name = models.CharField(max_length=128)
created_by = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
def __str__(self) -> str:
return self.name
MLAlgorithm model:
class MLAlgorithm(models.Model):
name = models.CharField(max_length=128)
created_by = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
parent_endpoint = models.ForeignKey('Endpoint', on_delete=models.CASCADE, related_name="mlalgorithms")
def __str__(self) -> str:
return self.name
ABTest model:
class ABTest(models.Model):
title = models.CharField(max_length=1000)
created_by = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
parent_endpoint = models.ForeignKey('Endpoint', on_delete=models.CASCADE, related_name="abtests")
parent_mlalgorithm_1 = models.ForeignKey('MLAlgorithm', on_delete=models.CASCADE, related_name="parent_mlalgorithm_1")
parent_mlalgorithm_2 = models.ForeignKey('MLAlgorithm', on_delete=models.CASCADE, related_name="parent_mlalgorithm_2")
def __str__(self) -> str:
return self.title
and defined their serializers:
Endpoint Serializer:
class EndpointSerializer(serializers.ModelSerializer):
class Meta:
model = Endpoint
read_only_fields = ("id", "name", "created_by", "created_at")
fields = read_only_fields
MLAlgorithm Serializer:
class MLAlgorithmSerializer(serializers.ModelSerializer):
class Meta:
model = MLAlgorithm
read_only_fields = (
"id", "name", "created_by", "created_at", "parent_endpoint")
fields = read_only_fields
ABTest Serializer:
class ABTestSerializer(serializers.ModelSerializer):
class Meta:
model = ABTest
read_only_fields = ("id", "created_at")
fields = (
"id", "title", "created_by", "created_at", "parent_endpoint", "parent_mlalgorithm_1", "parent_mlalgorithm_2")
Then i created a viewset for the ABTest:
class ABTestViewSet(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin):
serializer_class = ABTestSerializer
queryset = ABTest.objects.all()
My problem is in the ABTestView:
for example, i have created two endpoints, and each endpoint has two algorithms:
endpoint_1:
algorithm_1
algorithm_2
endpoint_2:
algorithm_3
algorithm_4
but when i select a specific endpoint in the view, i want only the specific algorithms to be shown not all the algorithms available in the database
enter image description here
i don't know how to force algorithm filtering in the view, should i filter the algorithms by their endpoints in the view or before serialization, unfortunately i am struggling to implement it.
Thank you in advance.
How could I count the relationship of the models below?
class Client(models.Model):
name = models.CharField(max_length=150)
class Pet(models.Model):
client = models.ForeignKey(Client, related_name='pet')
name = models.CharField(max_length=150)
class Photo(models.Model):
pet = models.ForeignKey(Pet, related_name='photo')
photo = models.ImageField(storage=DIR)
I would like to return the total pet and total photos taken of all pets dr to a single customer client, with the following answer:
[
{
"name": "john",
"totalPet": 3, // imagine 10 photos were taken of each pet
"totalPhoto": 30,
},
{
"name": "Mary",
"totalPet": 2, // imagine that 10 photos were taken of one and 5
// of another pet
"totalPhoto": 15,
},
]
My serializer is as follows:
class ClientSerializer(ModelSerializer):
totalPet = serializers.SerializerMethodField()
def get_totalPet(self, obj):
return obj.pet.count()
class Meta:
model = Client
fields = ('name', 'totalPet')
As can be observed, I can total the amount of pets for each customer, but I can't find a way to total the photos of all pets of a customer.
What would be the best way to do this photo count?
You can perform a filter on Photo model with your client.pet queryset, using the __in lookup.
At first, I would define a custom QuerySet for our Photo model:
from django.db import models
class PhotoQuerySet(models.QuerySet):
def for_client(self, client):
# Get all related pets to the current client
client_pets = client.pet.all()
# Filter Photos that are linked with these pets
return self.filter(pet__in=client_pets)
And then inside the model:
class Photo(models.Model):
...
objects = PhotoQuerySet.as_manager()
This will allow you to do the following: Photo.objects.for_client(client=...)
After that, you can use this method in the serializer:
class ClientSerializer(ModelSerializer):
total_pets = serializers.SerializerMethodField()
total_photos = serializers.SerializerMethodField()
def get_total_pets(self, obj):
return obj.pet.count()
def get_total_photos(self, obj):
# Calling our newly created method and aggregating count
return Photo.objects.for_client(client=obj).count()
class Meta:
model = Client
fields = ('name', 'total_pets', 'total_photos')
I've got for things that I want to model: vaccines, countries, diseases and medicines.
A disease is in N countries
A medicine cures N diseases
A vaccine prevents N diseases
My primary search method will be by country, listing vaccines and medicines through the disease connection.
I thought I'd do this by this model:
class Country(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Disease(models.Model):
name = models.CharField(max_length=100)
country = models.ManyToManyField(Country)
def __unicode__(self):
return self.name
class Vaccine(models.Model):
name = models.CharField(max_length=100)
diseases = models.ManyToManyField(Disease, blank=True)
def __unicode__(self):
return self.name
class Medicine(models.Model):
name = models.CharField(max_length=100, blank=True)
diseases = models.ManyToManyField(Disease, blank=True)
def __unicode__(self):
return self.name
And I search like this:
def vacc_for_country(request, country_id):
diseases = Disease.objects.filter(countries__pk=country_id)
vaccines = Vaccine.objects.filter(id__in=[d.id for d in [v.diseases for v in Vaccine.objects.all()]])
return serialize(vaccines)
but that doesn't work, I get: AttributeError at /vaccines/seek/countryId/3
'ManyRelatedManager' object has no attribute 'id'.
So how do I go from country_id to a list of vaccines?
I have no clue what you were going for there.
Vaccine.objects.filter(diseases__country__id=country_id)