Django开发OpenAI聊天机器人时出现Field 'id'类型错误求助
问题
开发OpenAI聊天机器人时,实现用户聊天记录保存功能触发TypeError,提示Field 'id' expected a number but got <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x0000025FE3733310>>,报错出现在chats = Chat.objects.filter(user=request.user)代码行。
报错堆栈
Traceback (most recent call last): File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\fields\__init__.py", line 2053, in get_prep_value return int(value) ^^^^^^^^^^ TypeError: int() argument must be a string, a bytes-like object or a real number, not 'SimpleLazyObject' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\Downloads\finalproject\finalproject\django_chatbot\chatbot\views.py", line 29, in chatbot chats = Chat.objects.filter(user=request.user) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\query.py", line 1436, in filter return self._filter_or_exclude(False, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\query.py", line 1454, in _filter_or_exclude clone._filter_or_exclude_inplace(negate, args, kwargs) File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\query.py", line 1461, in _filter_or_exclude_inplace self._query.add_q(Q(*args, **kwargs)) File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\sql\query.py", line 1534, in add_q clause, _ = self._add_q(q_object, self.used_aliases) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\sql\query.py", line 1565, in _add_q child_clause, needed_inner = self.build_filter( ^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\sql\query.py", line 1480, in build_filter condition = self.build_lookup(lookups, col, value) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\sql\query.py", line 1307, in build_lookup lookup = lookup_class(lhs, rhs) ^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\lookups.py", line 27, in __init__ self.rhs = self.get_prep_lookup() ^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\fields\related_lookups.py", line 166, in get_prep_lookup self.rhs = target_field.get_prep_value(self.rhs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Nathan A\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\db\models\fields\__init__.py", line 2055, in get_prep_value raise e.__class__( TypeError: Field 'id' expected a number but got <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x0000025FE3733310>>.
视图代码
def chatbot(request): chats = Chat.objects.filter(user=request.user) if request.method == 'POST': message = request.POST.get('message') response = ask_openai(message) chat = Chat(user=request.user, message=message, response=response, created_at=timezone.now()) chat.save() return JsonResponse({'message': message, 'response': response}) return render(request, 'index.html', {'chats': chats})
原因分析
错误根源是当前请求的用户是匿名用户(AnonymousUser):
- Django中,未登录用户的
request.user是由SimpleLazyObject包装的AnonymousUser对象,该对象没有有效的数字类型id; - Chat模型的
user字段是关联到User模型的外键,查询或创建时需要对应存在的用户id(数字类型),因此传入匿名用户对象会触发类型错误。
解决方案
方案1:强制用户登录后访问视图
使用Django内置的login_required装饰器,确保只有已认证用户才能访问该视图,未登录用户会被重定向到登录页面。
修改视图代码:
from django.contrib.auth.decorators import login_required @login_required def chatbot(request): chats = Chat.objects.filter(user=request.user) if request.method == 'POST': message = request.POST.get('message') response = ask_openai(message) chat = Chat(user=request.user, message=message, response=response, created_at=timezone.now()) chat.save() return JsonResponse({'message': message, 'response': response}) return render(request, 'index.html', {'chats': chats})
方案2:支持匿名用户存储聊天记录(可选)
如果需要允许匿名用户使用功能,需调整Chat模型和视图逻辑:
- 修改Chat模型,允许
user字段为空:
from django.db import models from django.contrib.auth.models import User class Chat(models.Model): user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) session_key = models.CharField(max_length=40, blank=True) # 用session标识匿名用户 message = models.TextField() response = models.TextField() created_at = models.DateTimeField(auto_now_add=True)
- 调整视图代码,区分登录用户和匿名用户:
def chatbot(request): # 过滤聊天记录:登录用户用user,匿名用户用session_key if request.user.is_authenticated: chats = Chat.objects.filter(user=request.user) else: # 确保session已创建 if not request.session.session_key: request.session.create() chats = Chat.objects.filter(session_key=request.session.session_key) if request.method == 'POST': message = request.POST.get('message') response = ask_openai(message) # 创建聊天记录 chat_data = { 'message': message, 'response': response } if request.user.is_authenticated: chat_data['user'] = request.user else: if not request.session.session_key: request.session.create() chat_data['session_key'] = request.session.session_key chat = Chat.objects.create(**chat_data) return JsonResponse({'message': message, 'response': response}) return render(request, 'index.html', {'chats': chats})
内容的提问来源于stack exchange,提问作者Memetendo64
相关产品推荐
相关产品推荐

