Python TypeError: Object of type 'User' is not JSON serializable after upgrading to Django 2.1
Python TypeError: Object of type 'User' is not JSON serializable after upgrading to Django 2.1
我正在尝试将 Django 项目从 Django(1.10) 升级到 Django(2.1),但在这样做时我遇到了一个错误,当时我使用 request.user.pk
传递一个用户创建一个对象。
到目前为止,这是我所拥有的:
来自 models.py
:
class TaggedArticle(models.Model):
user = models.ForeignKey(User, related_name='tagging', on_delete=models.CASCADE)
email = models.EmailField(max_length=255)
category_fit = models.CharField(choices=choices, max_length=255)
article = models.ForeignKey(Article, related_name='articles', on_delete=models.CASCADE)
link = models.URLField(max_length=255,)
relevant_feedback = models.TextField(blank=True)
category = models.CharField(max_length=255,)
created_at = models.DateTimeField(default=timezone.now, editable=False)
来自 forms.py
:
class TagForm(forms.ModelForm):
class Meta:
model = TaggedArticle
fields = ('user', 'category_fit', 'article', 'link', 'relevant_feedback', 'category',)
widgets = {
'category_fit': forms.RadioSelect()
}
从 views.py
:
class TagView(LoginRequiredMixin, generic.CreateView):
form_class = forms.TagForm
def post(self, request, *args, **kwargs):
try:
post_data = request.POST.copy()
post_data.update({'user': request.user.pk})
print(post_data.values)
form = forms.TagForm(post_data)
if form.is_valid():
tag = form.save(commit=False)
tag.user = request.user
tag.email = request.user.email
tag.save()
request.session['user'] = tag.user
request.session['email'] = tag.email
else:
print(form.errors)
return HttpResponse(form.errors, status=400)
print('going to redirect after successful tagging.')
return HttpResponseRedirect(reverse('users:dashboard'))
except Exception as exp:
logging.error(exp)
print('error is: {}'.format(exp))
return HttpResponse(exp, status=400)
Update: Here's the HTML form from template:
<form class="omb_loginForm" action="{% url 'users:tagged' %}" method="POST">
{% csrf_token %}
<table class="table">
<thead><h4> Tag this Article:</h4></thead>
<tbody>
<tr>
<th>Reviewer:</th>
<td></td>
<td>{{ user.username }}</td>
</tr>
<tr>
<th>No of Article Reviewed:</th>
<td></td>
<td>{{ user.tagging.all |length }}</td>
</tr>
<tr>
<th>Category:</th>
<td></td>
<td>{{ art.category }}
<input type="hidden" value="{{ art.id }}" name="article"/>
<input type="hidden" value="{{ art.link }}" name="link"/>
<input type="hidden" value="{{ art.category }}" name="category"/>
</td>
</tr>
<tr>
<th>Does the text of this article fit in this category?</th>
<td><label class="radio-inline"><input type="radio" name="category_fit"
value="yes">Yes</label></td>
<td><label class="radio-inline"><input type="radio" name="category_fit"
value="no">No</label></td>
<td><label class="radio-inline"><input type="radio" name="category_fit"
value="not sure">Not Sure</label>
</td>
</tr>
<tr>
<th><label for="comment">Copy and then paste in a relevant sentence for categorization:</label></th>
<td colspan="3">
<textarea class="form-control" rows="7" id="comment"
name="relevant_feedback"></textarea>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-lg btn-primary btn-block" type="submit">Tag</button>
</form>
所以,在 POST
请求它 returns 错误如下:
TypeError: Object of type 'User' is not JSON serializable
当我打印 form.errors
然后它打印:
<ul class="errorlist"><li>user<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul>
那么,这里有什么问题吗?
提前致谢!
由于您的 TaggedArticle
实例中的 user
是当前登录的用户,我认为您不需要在 TagForm
中指定 user
。您可以从 TagForm
的 fields
中删除 user
:
class TagForm(forms.ModelForm):
class Meta:
model = TaggedArticle
fields = ('category_fit', 'article', 'link', 'relevant_feedback', 'category',)
widgets = {
'category_fit': forms.RadioSelect()
}
现在,由于您的视图会自动将当前登录的用户保存为 user
以供 TaggedArticle
,因此无需再做任何工作,错误也可能不会发生。
编辑:可能错误是由行产生的:
request.session['user'] = tag.user
此处User对象不可JSON序列化,Django在1.6版本后使用JSON序列化session数据。因此,您可能需要存储用户 ID 而不是 User 对象。
示例:
request.session['user'] = tag.user.id
我正在尝试将 Django 项目从 Django(1.10) 升级到 Django(2.1),但在这样做时我遇到了一个错误,当时我使用 request.user.pk
传递一个用户创建一个对象。
到目前为止,这是我所拥有的:
来自 models.py
:
class TaggedArticle(models.Model):
user = models.ForeignKey(User, related_name='tagging', on_delete=models.CASCADE)
email = models.EmailField(max_length=255)
category_fit = models.CharField(choices=choices, max_length=255)
article = models.ForeignKey(Article, related_name='articles', on_delete=models.CASCADE)
link = models.URLField(max_length=255,)
relevant_feedback = models.TextField(blank=True)
category = models.CharField(max_length=255,)
created_at = models.DateTimeField(default=timezone.now, editable=False)
来自 forms.py
:
class TagForm(forms.ModelForm):
class Meta:
model = TaggedArticle
fields = ('user', 'category_fit', 'article', 'link', 'relevant_feedback', 'category',)
widgets = {
'category_fit': forms.RadioSelect()
}
从 views.py
:
class TagView(LoginRequiredMixin, generic.CreateView):
form_class = forms.TagForm
def post(self, request, *args, **kwargs):
try:
post_data = request.POST.copy()
post_data.update({'user': request.user.pk})
print(post_data.values)
form = forms.TagForm(post_data)
if form.is_valid():
tag = form.save(commit=False)
tag.user = request.user
tag.email = request.user.email
tag.save()
request.session['user'] = tag.user
request.session['email'] = tag.email
else:
print(form.errors)
return HttpResponse(form.errors, status=400)
print('going to redirect after successful tagging.')
return HttpResponseRedirect(reverse('users:dashboard'))
except Exception as exp:
logging.error(exp)
print('error is: {}'.format(exp))
return HttpResponse(exp, status=400)
Update: Here's the HTML form from template:
<form class="omb_loginForm" action="{% url 'users:tagged' %}" method="POST">
{% csrf_token %}
<table class="table">
<thead><h4> Tag this Article:</h4></thead>
<tbody>
<tr>
<th>Reviewer:</th>
<td></td>
<td>{{ user.username }}</td>
</tr>
<tr>
<th>No of Article Reviewed:</th>
<td></td>
<td>{{ user.tagging.all |length }}</td>
</tr>
<tr>
<th>Category:</th>
<td></td>
<td>{{ art.category }}
<input type="hidden" value="{{ art.id }}" name="article"/>
<input type="hidden" value="{{ art.link }}" name="link"/>
<input type="hidden" value="{{ art.category }}" name="category"/>
</td>
</tr>
<tr>
<th>Does the text of this article fit in this category?</th>
<td><label class="radio-inline"><input type="radio" name="category_fit"
value="yes">Yes</label></td>
<td><label class="radio-inline"><input type="radio" name="category_fit"
value="no">No</label></td>
<td><label class="radio-inline"><input type="radio" name="category_fit"
value="not sure">Not Sure</label>
</td>
</tr>
<tr>
<th><label for="comment">Copy and then paste in a relevant sentence for categorization:</label></th>
<td colspan="3">
<textarea class="form-control" rows="7" id="comment"
name="relevant_feedback"></textarea>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-lg btn-primary btn-block" type="submit">Tag</button>
</form>
所以,在 POST
请求它 returns 错误如下:
TypeError: Object of type 'User' is not JSON serializable
当我打印 form.errors
然后它打印:
<ul class="errorlist"><li>user<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul>
那么,这里有什么问题吗?
提前致谢!
由于您的 TaggedArticle
实例中的 user
是当前登录的用户,我认为您不需要在 TagForm
中指定 user
。您可以从 TagForm
的 fields
中删除 user
:
class TagForm(forms.ModelForm):
class Meta:
model = TaggedArticle
fields = ('category_fit', 'article', 'link', 'relevant_feedback', 'category',)
widgets = {
'category_fit': forms.RadioSelect()
}
现在,由于您的视图会自动将当前登录的用户保存为 user
以供 TaggedArticle
,因此无需再做任何工作,错误也可能不会发生。
编辑:可能错误是由行产生的:
request.session['user'] = tag.user
此处User对象不可JSON序列化,Django在1.6版本后使用JSON序列化session数据。因此,您可能需要存储用户 ID 而不是 User 对象。 示例:
request.session['user'] = tag.user.id