Создание api для получения информации из многотомного поля
Я делаю API с использованием django rest framework и то, что он должен делать, это возвращать фильмы, которые имеют определенный жанр.
И я не знаю, как это сделать. потому что модель фильма имеет много полей под названием filmGenre и я хочу предпочтительно сделать этот api путем расширения класса ModelSerializer.
# Models.py
class Genre(models.Model):
genreID = models.AutoField(primary_key=True)
nameOf = models.CharField(max_length=100, unique=True)
details = models.TextField(null=True)
class Film(models.Model):
filmID = models.AutoField(primary_key=True)
title = models.CharField(max_length=150)
filmGenre = models.ManyToManyField(Genre)
# Serializers.py
class GenreRetrieveSerializer(serializers.ModelSerializer):
# TO BE DONE
может ли кто-нибудь помочь мне с этой проблемой?
Вы можете получить доступ к связанным объектам "многие-ко-многим" благодаря "_set". Что-то вроде этого должно работать:
class FilmSerializer(serializers.ModelSerializer):
class Meta:
model = Film
fields = ('filmID', 'title')
class GenreRetrieveSerializer(serializers.ModelSerializer):
film_set = FilmSerializer(many=True)
class Meta:
model = Genre
fields = '__all__'
Ответ, который дал @ThomasGth, работает только если у вас есть 1 поле foreign-key или many-to-many.
чтобы сделать это с двумя внешними ключами, вы должны назвать поле в вашем serializers.py, именем, которое было дано полю related_name в вашем models.py. поэтому код должен быть примерно таким:
class CelebrityRetrieveSerializer(serializers.ModelSerializer):
class FilmSerializer(serializers.ModelSerializer):
class Meta:
model = Film
fields = ('title',)
actor = FilmSerializer(read_only=True, many=True,)
director = FilmSerializer(read_only=True, many=True,)
class Meta:
model = Celebrity
fields = '__all__'
Вы также должны убедиться, что значение related_name не конфликтует с другими именами, которые вы использовали в коде. например, если вы установите значение related_name = Film, это может вызвать проблемы.
models.py
class Actor(models.Model):
image = models.ImageField("Image", upload_to='cast/')
name = models.CharField("Name", max_length=255)
type = models.CharField('Type', max_length=255, default='Actor')
description = models.TextField('About')
slug = models.SlugField("Link", unique=True)
class Meta:
verbose_name = "Actor"
verbose_name_plural = "Cast"
def current_path(self):
return "/Actor/" + str(self.name) + "/"
def get_absolute_url(self):
return reverse('actor_detail_url', kwargs={'slug': self.slug})
def __str__(self):
return self.name
class Movie(models.Model):
poster = models.ImageField(
'Poster', blank=True, upload_to='posters/')
movie = models.FileField("Movie Copy", upload_to="movies/")
title = models.CharField('Title', max_length=255)
description = models.TextField('Description')
genre = models.ManyToManyField(
Genre, blank=True, verbose_name='Genre')
director = models.ManyToManyField(
Director, blank=True, verbose_name='Director')
cast = models.ManyToManyField(
Actor, blank=True, verbose_name='Cast')
imdb_rating = models.ForeignKey(
IMDb_Rating, on_delete=models.CASCADE, null=True, verbose_name="IMDb Rating")
rotten_tomatoes_rating = models.ForeignKey(
Rotten_Tomatoes_Rating, on_delete=models.CASCADE, null=True, verbose_name="Rotten Tomatoes Rating")
other_rating = models.ForeignKey(
Other_Rating, on_delete=models.CASCADE, null=True, verbose_name="Other Rating")
budget = models.CharField('Budget', max_length=255,
default="20 million", blank=True)
box_office = models.CharField(
'Box Office', max_length=255, default="1.50 billion", blank=True)
composers = models.ManyToManyField(
Composer, blank=True, verbose_name="Composers")
date = models.DateField('Release Date', default=timezone.now)
country = CountryField(blank_label='Select Country')
Quality = models.CharField("Quality", max_length=255, default="720p")
runtime = models.CharField("Runtime", max_length=255, default="1h 20m")
publication = models.BooleanField("Publication", default=True)
slug = models.SlugField('Link', unique=True)
class Meta:
verbose_name = 'Movie'
verbose_name_plural = 'Movies'
def get_absolute_url(self):
return reverse('movie_detail_url', kwargs={'slug': self.slug})
def __str__(self):
return self.title
movie_detail.html
<div class="cast-column">
{% for actor in movie.cast.all %}
<a href="{% url 'actor_detail_url' actor.slug %}">
<div class="actor" style="{% if not forloop.first %} margin-left: 8px; {% endif %}">
<div class="actor-picture">
<img src="{{actor.image.url}}" alt="{{actor.name}}">
</div>
<div class="actor-n_r">
<div class="actor-name">{{actor.name}}</div>
<div class="actor-role">{{role.role}}</div>
</div>
</div>
</a>
{% endfor %}
</div>