You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST多数据查询报错:MultipleObjectsReturned问题求助

Hey there! The issue here is super straightforward—you're using the wrong view class for your use case. Let me break it down and fix it for you:

Why You're Getting the MultipleObjectsReturned Error

RetrieveUpdateDestroyAPIView is built to handle single objects (that's what the "Retrieve" in the name means). Under the hood, it uses the get() method to fetch one exact record matching your lookup_field value. When multiple Subject entries exist for the same course, get() throws this error because it expects exactly one result, not multiple.

Since your goal is to fetch all subjects linked to a specific course, you need a view designed for lists of objects instead.

Fix 1: Switch to a List View

Replace RetrieveUpdateDestroyAPIView with ListAPIView (use ListCreateAPIView instead if you also need to create new subjects via this endpoint). Then override the get_queryset method to filter subjects by the course ID from your URL:

# views.py
from rest_framework import generics

class ViewSubjectAccordingCourse(generics.ListAPIView):
    """Fetch all subjects associated with a specific course"""
    serializer_class = SubjectSerializer

    def get_queryset(self):
        # Pull the course ID from the URL parameter
        course_id = self.kwargs['course']
        # Return only subjects that match this course ID
        return Subject.objects.filter(course=course_id)

Fix 2: Fix the Broken __str__ Method in Your Model

I spotted a bug in your Subject model—your __str__ method tries to return self.title, but there's no title field defined in the model! This will cause an AttributeError whenever Django tries to display a Subject instance. Update it to use an existing field like subject or course:

# models.py
def __str__(self):
    return f"{self.subject}"  # Or use f"{self.course} - {self.subject}" for more context

Fix 3: Clean Up Redundant Configuration

You can remove lookup_field = 'course' from both your serializer and view now. We're using get_queryset to filter results, so that setting is no longer needed. Your existing URL pattern works perfectly as-is.

Optional: Improve Your Model's Course Field (Best Practice)

If course is supposed to reference a separate Course model (instead of just storing an ID as a string), you should swap the CharField for a ForeignKey to enforce database integrity and unlock better Django ORM features:

# models.py
# First, define your Course model (if you haven't already)
class Course(models.Model):
    name = models.CharField(max_length=255)
    # Add any other fields relevant to your course

class Subject(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='subjects')
    # Keep your other existing fields (subject, description, etc.)

With this change, you could simplify the view even further by using course.subjects.all() instead of filtering, but that's an optional upgrade once you get the basic version working.

After making these changes, hitting http://127.0.0.1:8000/subjects/course/23/ will return a list of all subjects linked to course 23, regardless of how many there are.

内容的提问来源于stack exchange,提问作者Ganesh Palte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:58:13