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
相关产品推荐
相关产品推荐

