You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:54:08