如何使用Django表单更新模型记录 实现电影类Tinder滑动功能
问题解决方案
核心问题根因
- 表单提交时没有绑定待更新的电影实例,Django ModelForm默认执行新增操作
- 实例方法中访问类变量没有加
self.前缀导致报错,且类变量是全局共享的,多用户访问时数据会混乱 - 提交表单时没有传递当前操作的电影ID,后端无法定位要更新的记录
修改后的代码
models.py(仅优化异常风险方法,原有逻辑不变)
class Movie(models.Model): movie_name = models.CharField(max_length=300) movie_description = models.TextField(default='') movie_genre = models.CharField(max_length=100) movie_date_released = models.DateField(null=True) movie_swiped = models.BooleanField(default = False) def __str__(self): return self.movie_name def is_exists(self): ''' 优化判断逻辑,避免查询不到时抛出异常 ''' return Movie.objects.filter(movie_name=self.movie_name).exists()
forms.py 无需修改
class MovieSwipeForm(ModelForm): class Meta: model = Movie fields = ('movie_swiped',)
views.py(核心逻辑修改)
class RoomSwipeView(APIView): serializer_class = MovieSerializer def get(self, request): # 初始化滑动记录到session,避免首次访问报错 if 'swiped_movies' not in request.session: request.session['swiped_movies'] = [] movie_id = request.GET.get('id') if movie_id: queryset = Movie.objects.filter(id=movie_id) else: queryset = Movie.objects.all() form = MovieSwipeForm() return render(request,'swipe.html',{'details':queryset, 'form':form}) def post(self, request): submitted = False # 从POST参数中取当前操作的电影ID movie_id = request.POST.get('movie_id') # 先查询到待更新的电影实例 movie_obj = Movie.objects.get(id=movie_id) # 实例化表单时传入instance参数,指定更新该实例 form = MovieSwipeForm(request.POST, instance=movie_obj) if form.is_valid(): swiped = form.save() # 滑动为True时添加到session存储的滑动列表 if swiped.movie_swiped: swiped_list = request.session['swiped_movies'] swiped_list.append(swiped.id) request.session['swiped_movies'] = swiped_list submitted = True # 保持页面原有展示逻辑 if request.GET.get('id'): queryset = Movie.objects.filter(id=request.GET.get('id')) else: queryset = Movie.objects.all() return render(request,'swipe.html',{'details':queryset, 'form':form,'submitted':submitted})
swipe.html(新增隐藏字段传递电影ID)
<html> <body> <h1> Movie Details</h1> {% for obj in details %} {{obj.movie_name}}<br/> Description: {{obj.movie_description}}<br/> Genre: {{obj.movie_genre}}<br/> Date Released: {{obj.movie_date_released}}<br/> {% if submitted %} Success {% else %} <form action="" method="post"> {% csrf_token %} <!-- 新增隐藏字段传递当前电影ID --> <input type="hidden" name="movie_id" value="{{ obj.id }}"> {{ form.as_p }} <input type="submit" value="Submit"> </form> {% endif %} <br/><br/> {% endfor %} </body> </html>
关键修改说明
- 表单实例化时添加
instance参数,Django就会执行更新操作而非新增 - 用Django自带的session存储用户的滑动记录,每个用户的数据独立,不会冲突,也不需要手动维护类变量
- 表单中新增隐藏字段传递当前操作的电影ID,后端可以准确定位要更新的记录
- 所有变量访问都在方法内部处理,避免类变量全局共享导致的异常和数据混乱
内容的提问来源于stack exchange,提问作者imtryin123
相关产品推荐
相关产品推荐

