简体   繁体   中英

How do I query a Foreign key, but in reverse and list them in Django Rest Framework?

I'm having a hard time getting my head around this for some reason. I know how to do this in plain Django, but not sure how to do this in DRF.

class Novel(models.Model):
 name = models.CharField(max_length = 100)
 image = models.URLField(blank = True)
 linkNU = models.URLField(blank = True)
 author = models.ForeignKey(Author, on_delete = models.CASCADE, null = True)
 category = models.ManyToManyField(Category)
 description = models.TextField(blank = True)
 slug = models.SlugField(primary_key = True, default = None, max_length=100)
 numOfChaps = models.IntegerField(default = 0)
 novelStatus = models.BooleanField(default = True) #True will be for Ongoing, False for Completed
 def __str__(self):
    return self.name

Chapter Model looks like this

class Chapter(models.Model):
 index = models.IntegerField(default = None, blank = True)
 text = models.TextField(max_length=None)
 title = models.TextField(max_length = 100)
 novelParent = models.ForeignKey(Novel, on_delete = models.CASCADE, verbose_name = "chapter")
 nextChap = models.BooleanField(default = False)
 novSlugChapSlug = models.CharField( max_length = 100, blank = True, default = None)
 
def __str__(self):
    return f"Chapter {self.index} - {self.novelParent}"

Right now this is what I have for ChapterSerializer but it doesn't work:

class ChapterSerializer(serializers.ModelSerializer):
 novel = serializers.CharField(source = 'novelParent.name')
 novSlug = serializers.CharField(source = 'novelParent.slug')

 class Meta:
    model = Chapter
    fields = "__all__"
    # fields = ('index','title','text','nextChap','novel','novSlug','novSlugChapSlug')

I've read around and feel like it probably is going to be done in the ModelViewSet's def list method. So here's what I have for that right now, which also doesn't work:

class ChapterSerializerView(viewsets.ViewSet):
 permission_classes = [ReadOnly]
 queryset = Chapter.objects.all()
 def list(self, request):
    queryset = Chapter.objects.all()
    serializer = ChapterSerializer(queryset, many=True)
    return Response(serializer.data)
# serializer_class = ChapterSerializer
 def retrieve(self, request, pk=None):
    queryset = Chapter.objects.all()
    chapter = get_object_or_404(queryset, novSlugChapSlug=pk)
    serializer = ChapterSerializer(chapter)
    return Response(serializer.data)

So basically what I need is when I send an API request, for ex /api/chapters/harry-potter, it lists out all the chapter index and title for the Chapter model, which matches the slug for Novel model.

Thanks for the help:)

Create a SerializerMethodField.

class ChapterSerializer(serializers.ModelSerializer):
 novelInfo = serializers.SerializerMethodField()

 class Meta:
    model = Chapter
    fields = ['novelInfo', 'index', 'text', 'title', ..]
    
    def get_novelInfo(self,obj):
        name = obj.novelParent.name
        slug = obj.novelParent.slug
        return {'name': name, 'slug': slug}

More about SerializerMethodField Documentation .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM