Django实现CRUD功能时更新Member数据遭遇TypeError(expected string or bytes-like object)问题求助
先看你遇到的TypeError: expected string or bytes-like object,这个错误的直接原因在你的update视图代码里:
member.date = request.POST.get('date', False),
注意这行末尾的逗号!它会把member.date赋值成一个元组(比如('2021-02-27',)),而Django的DateField期望接收的是字符串、date对象或者None,当它尝试解析这个元组时就会抛出类型错误。
除此之外,你的代码还有几个其他问题,一起帮你修复:
1. 修复Update视图的核心问题
修改views.py里的update函数,解决逗号、不存在的字段、日期默认值和更新时间的问题:
@login_required def update(request, id): member = Member.objects.get(id=id) # 去掉每个赋值行末尾的逗号! member.username = request.POST.get('username') member.mobile_number = request.POST.get('mobile_number') # 移除member.description,你的Member模型里没有这个字段 member.location = request.POST.get('location') # 日期如果没拿到值,保留原来的日期,而不是传False date_value = request.POST.get('date') if date_value: member.date = date_value # 更新updated_at为当前时间 member.updated_at = datetime.datetime.now() member.save() messages.success(request, 'Member was updated successfully!') return redirect('/list')
2. 修复edit.html里的Location字段
你的edit.html中,Location的input标签没有name="location"属性,导致提交表单时request.POST.get('location')拿不到值,会把location设为空,甚至触发模型的非空验证。修改这部分:
<input type="text" id="inputLoca" class="form-control" value="{{ members.location }}" placeholder="Enter Location" name="location" required="">
加上name="location"即可。
3. 修复Member模型的日期字段定义
你的models.py里的date、created_at、updated_at定义有问题:DateField和DateTimeField的第一个参数是verbose_name(可选的字段别名),不是日期格式字符串。正确的做法是用auto_now_add和auto_now来自动处理创建和更新时间,或者设置default:
class Member(models.Model): username = models.CharField(max_length=40, blank=False) email = models.EmailField(max_length = 40, blank = False) mobile_number = models.CharField(max_length=10, blank=True) location = models.TextField(max_length=255, blank=False) # 如果你希望手动设置date,就保留DateField,不需要传格式参数 date = models.DateField() # 创建时自动设置当前时间,后续不会自动更新 created_at = models.DateTimeField(auto_now_add=True) # 每次保存时自动更新为当前时间 updated_at = models.DateTimeField(auto_now=True)
这样你就不用在create和update视图里手动设置created_at和updated_at了,Django会自动处理。
4. 额外优化:使用get_object_or_404避免DoesNotExist错误
在edit和update视图里,用get_object_or_404代替Member.objects.get(id=id),这样如果用户访问了不存在的会员ID,会返回404页面而不是服务器错误:
from django.shortcuts import get_object_or_404 # edit视图 def edit(request, id): members = get_object_or_404(Member, id=id) context = {'members': members} return render(request, 'edit.html', context) # update视图 def update(request, id): member = get_object_or_404(Member, id=id) # ... 其余代码不变
做完这些修改后,你的编辑/更新功能应该就能正常工作了。
内容的提问来源于stack exchange,提问作者Danish Khan

