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。您可以从 TagFormfields 中删除 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