Django通用关系-**类型的对象不是JSON可序列化的

时间:2019-05-04 16:33:15

标签: python django django-rest-framework

对Django还是一个新手,请耐心等待。

我正在尝试遵循Django示例https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/

我正在尝试使用tests.py为学生1创建笔记。

这是tests.py:

from django.test import TestCase
from gsndb.models import *
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User

# Create your tests here.

student = Student.objects.get(id=4)
text = "The student is content"
user = User.objects.get(id=2)

new_note = Note(text=text, content_object = student, user = user)

new_note.save()

我希望它为学生1创建一个笔记。但是,当我运行测试时,出现此错误:

Object of type 'Student' is not JSON serializable

这是回溯:

Environment:


Request Method: GET
Request URL: http://localhost/gsndb/note/

Django Version: 2.1.7
Python Version: 3.6.8
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'corsheaders',
 'rest_framework',
 'user_app.apps.UserAppConfig',
 'gsndb.apps.GsndbConfig']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/usr/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/usr/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  156.                 response = self.process_exception_by_middleware(e, request)

File "/usr/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  154.                 response = response.render()

File "/usr/lib/python3.6/site-packages/django/template/response.py" in render
  106.             self.content = self.rendered_content

File "/usr/lib/python3.6/site-packages/rest_framework/response.py" in rendered_content
  72.         ret = renderer.render(self.data, accepted_media_type, context)

File "/usr/lib/python3.6/site-packages/djangorestframework_camel_case2/render.py" in render
  9.                                                          **kwargs)

File "/usr/lib/python3.6/site-packages/rest_framework/renderers.py" in render
  107.             allow_nan=not self.strict, separators=separators

File "/usr/lib/python3.6/site-packages/rest_framework/utils/json.py" in dumps
  28.     return json.dumps(*args, **kwargs)

File "/usr/lib/python3.6/json/__init__.py" in dumps
  238.         **kw).encode(obj)

File "/usr/lib/python3.6/json/encoder.py" in encode
  199.         chunks = self.iterencode(o, _one_shot=True)

File "/usr/lib/python3.6/json/encoder.py" in iterencode
  257.         return _iterencode(o, 0)

File "/usr/lib/python3.6/site-packages/rest_framework/utils/encoders.py" in default
  68.         return super(JSONEncoder, self).default(obj)

File "/usr/lib/python3.6/json/encoder.py" in default
  180.                         o.__class__.__name__)

Exception Type: TypeError at /gsndb/note/
Exception Value: Object of type 'Student' is not JSON serializable

这里是models.py

class Note(models.Model):
    user = models.ForeignKey(
        get_user_model(),
        on_delete = models.PROTECT,
    )
    created = models.DateTimeField(default = timezone.now)
    text = models.TextField()

    # Below the mandatory fields for generic relation
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type','object_id')

class Student(models.Model):
    current_school = models.ForeignKey(
        "School",
        null = True,
        on_delete = models.PROTECT,
    )
    current_program = models.ForeignKey(
        "Program",
        null = True,
        on_delete = models.PROTECT,
    )
    first_name = models.CharField(max_length = 35, blank=True)
    last_name = models.CharField(max_length = 35, blank=True)
    middle_name = models.CharField(max_length = 35, blank=True)
    """Establish choices for Gender"""
    GENDER_CHOICES = (
        ("M", 'Male'),
        ("F", 'Female'),
        ("NB", 'NonBinary'),
    )
    gender = models.CharField(
            max_length = 2,
            blank = True,
            choices = GENDER_CHOICES,
    )
    birth_date = models.DateField(null = True)
    state_id = models.BigIntegerField(null = True)
    """Establish choices for Grade Year"""
    GRADE_YEAR_CHOICES = (
        (0, 'Kindergarten'),
        (1, 'First Grade'),
        (2, 'Second Grade'),
        (3, 'Third Grade'),
        (4, 'Fourth Grade'),
        (5, 'Fifth Grade'),
        (6, 'Sixth Grade'),
        (7, 'Seventh Grade'),
        (8, 'Eighth Grade'),
        (9, 'Ninth Grade'),
        (10, 'Tenth Grade'),
        (11, 'Eleventh Grade'),
        (12, 'Twelfth Grade'),
    )
    grade_year = models.SmallIntegerField(
        choices = GRADE_YEAR_CHOICES,
        null = True,
    )
    reason_in_program = models.TextField(blank=True)
    notes = GenericRelation(Note)

这是serializers.py:

class NoteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Note
        fields = ("user",
            "created",
            "text",
            "content_type",
            "object_id",
            "content_object")

class StudentSerializer(serializers.BaseSerializer):

        def to_representation(self, student_obj):
            notes = NoteSerializer(many = True)
            notes_json = notes.data

            return {
                "current_school": student_obj.current_school.id,
                "current_program": student_obj.current_program.id,
                "first_name": student_obj.first_name,
                "last_name": student_obj.last_name,
                "middle_name": student_obj.middle_name,
                "gender": student_obj.gender,
                "birth_date": student_obj.birth_date,
                "state_id": student_obj.state_id,
                "grade_year": student_obj.grade_year,
                "reason_in_program": student_obj.reason_in_program,
                "notes": notes_json,
            }

这是我的views.py:

class NoteList(generics.ListCreateAPIView):
    queryset = Note.objects.all()
    serializer_class = NoteSerializer

感谢您的时间!

1 个答案:

答案 0 :(得分:1)

弄清楚了我的问题。在我看来。

我的观点是

class NoteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Note
        fields = ("user",
            "created",
            "text",
            "content_type",
            "object_id",
            "content_object")

我需要删除“ content_object”,因为它不是JSON可序列化的。它需要看起来像这样:

class NoteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Note
        fields = ("user",
            "created",
            "text",
            "content_type",
            "object_id")

感谢所有帮助!