Django Generic Relations - ** 类型的对象不是 JSON 可序列化的
Posted
技术标签:
【中文标题】Django Generic Relations - ** 类型的对象不是 JSON 可序列化的【英文标题】:Django Generic Relations - Object of Type ** is Not JSON Serializable 【发布时间】:2019-09-22 20:59:25 【问题描述】:对 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
感谢您的宝贵时间!
【问题讨论】:
在这一行 'new_note = Note(text=text, content_object = student, user = user)' 如果您的意思是创建新对象,然后像这样创建: new_note = Note.objects.create(text=text, content_object = student, user = user) @chiragsoni 谢谢!能问下有什么区别吗?此外,它仍然导致相同的错误,即 student 不是 json 可序列化的。有什么想法吗? 阅读:***.com/questions/26672077/… 谢谢!知道为什么它仍然说学生不是 json 可序列化的 【参考方案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")
感谢大家的帮助!
【讨论】:
以上是关于Django Generic Relations - ** 类型的对象不是 JSON 可序列化的的主要内容,如果未能解决你的问题,请参考以下文章
django 1.9 中的 from django.views.generic.simple import direct_to_template 相当于啥
python - Django4 - 表格&generic view