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

Django列表间项目迁移遇问题:项目仍留存原列表

Django游戏列表迁移问题修复

核心问题

问题本质是修改仅停留在内存列表,未同步到数据库,且添加到已玩列表时未删除正在玩列表的数据库记录,导致刷新页面后旧数据重新加载。同时模型设计不符合Django最佳实践,加剧了问题复杂度。

修复步骤

1. 优化模型设计

用Django外键关联替代手动存储ID,避免关联错误,同时添加唯一性约束防止重复条目:

from django.contrib.auth.models import User
from django.db import models

class Game(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True, null=True, max_length=500)
    image = models.URLField(blank=True, null=True, max_length=500)
    genre = models.CharField(blank=True, null=True, max_length=200)
    platform = models.CharField(blank=True, null=True, max_length=200)
    developer = models.CharField(blank=True, null=True, max_length=200)
    publisher = models.CharField(blank=True, null=True, max_length=200)
    added_by = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return f"ID# { self.id }: { self.title }"

class Playinglist(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    started_on = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('user', 'game')  # 每个用户每个游戏仅存一次

class Playedlist(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    finished_on = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('user', 'game')

2. 修正视图逻辑

确保添加到已玩列表时,同步删除正在玩列表的数据库记录,同时简化列表查询逻辑:

from django.shortcuts import redirect, get_object_or_404, render
from django.utils import timezone
from .models import Game, Playinglist, Playedlist

def add_to_playinglist(request, game_id):
    game = get_object_or_404(Game, id=game_id)
    playing_entry = Playinglist.objects.filter(user=request.user, game=game).first()
    
    if playing_entry:
        playing_entry.delete()
    else:
        # 若游戏在已玩列表,先移除避免冲突
        Playedlist.objects.filter(user=request.user, game=game).delete()
        Playinglist.objects.create(user=request.user, game=game, started_on=timezone.now())
    
    return redirect("profile")

def add_to_playedlist(request, game_id):
    game = get_object_or_404(Game, id=game_id)
    played_entry = Playedlist.objects.filter(user=request.user, game=game).first()
    
    if played_entry:
        played_entry.delete()
    else:
        # 从正在玩列表删除对应条目,完成迁移
        Playinglist.objects.filter(user=request.user, game=game).delete()
        Playedlist.objects.create(user=request.user, game=game, finished_on=timezone.now())
    
    return redirect("profile")

def profile(request):
    # 直接从数据库查询关联数据,无需手动处理内存列表
    playinglist = Playinglist.objects.filter(user=request.user).select_related('game')
    playedlist = Playedlist.objects.filter(user=request.user).select_related('game')
    
    playinglist_items = [entry.game for entry in playinglist]
    playedlist_items = [entry.game for entry in playedlist]
    
    context = {
        'playinglist_items': playinglist_items,
        'playedlist_items': playedlist_items,
        'playing_count': len(playinglist_items),
        'finished_count': len(playedlist_items)
    }
    return render(request, 'profile.html', context)  # 替换为你的模板路径

关键修复点

  • 用ForeignKey替代手动存储的game_id和username,利用Django ORM自动处理关联,避免ID匹配错误。
  • 在add_to_playedlist中添加删除Playinglist条目的逻辑,确保数据库中“正在玩”列表的记录被真正移除。
  • profile视图直接从数据库获取最新数据,不再依赖内存列表的修改,保证显示内容与数据库状态一致。
  • 添加unique_together约束,防止同一个游戏在同一用户的列表中重复出现。

内容的提问来源于stack exchange,提问作者agold95

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:57:53