【问题标题】:Python TypeError: Object of type 'User' is not JSON serializable after upgrading to Django 2.1Python TypeError:升级到 Django 2.1 后,“用户”类型的对象不是 JSON 可序列化的
【发布时间】:2019-07-24 18:54:05
【问题描述】:

我正在尝试将 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)

更新:这是来自模板的 HTML 表单:

<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 请求中,它会返回以下错误:

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>

那么,这里有什么问题呢?

提前致谢!

【问题讨论】:

  • 在选择user时,您能显示正在使用的模板以及显示的选项吗?
  • 用户将是当前登录用户,这就是为什么我没有从模板中传递它并将其添加到视图中的request.POST 中。
  • 那为什么要在表单中填写user字段呢?
  • 因为我需要保存用户的相关TaggedArticle,你可以看到我在模型中提到了related_name属性。
  • 你能展示你的模板吗?

标签: python django python-3.x django-2.1 django-1.10


【解决方案1】:

由于您的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()
        }

现在,由于您的视图自动将当前登录的用户保存为userTaggedArticle,因此无需进行更多工作,也可能不会发生错误。

编辑:也许错误是由以下行产生的:

request.session['user'] = tag.user

这里的 User 对象不是 JSON 可序列化的,Django 在 1.6 版本之后使用 JSON 序列化会话数据。因此,您可能需要存储用户 ID 而不是 User 对象。 示例:

request.session['user'] = tag.user.id

【讨论】:

  • 嗨@Sanip,还是和TypeError: Object of type 'User' is not JSON serializable一样的错误
猜你喜欢
  • 2020-12-02
  • 2020-12-13
  • 2014-08-05
  • 2018-11-27
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 2019-11-21
相关资源
最近更新 更多