首页 > 解决方案 > Django - 无法使用视图功能将新条目保存到数据库

问题描述

这是我正在使用的视图功能

视图.py

def favorite_item (request, pk):
    favitem = get_object_or_404(Item, pk=pk)
    userfav = Favorite.objects.filter(user=request.user)
    for items in userfav:
        if items.item == favitem:
            items.delete()
        else:
            new_entry = Favorite(item=favitem, user=request.user)
            new_entry.save()

    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

删除已经存在的行的部分工作正常:

   if items.item == favitem:
        items.delete()

但我认为问题出在我尝试添加新行的地方,只是没有返回任何内容,甚至没有引发错误!

else:
    new_entry = Favorite(item=favitem, user=request.user)
    new_entry.save()

标签: pythondjango

解决方案


逻辑可能是错误的。favitem可能是用户想要收藏/取消收藏的项目。此外userfav是该用户最喜欢的项目的列表。

if-循环else中的子句for

但是随后您开始迭代该列表。如果Favorite是要收藏的项目,则将其删除(这可能是正确的)。但是如果用户收藏列表中的项目不是该用户的收藏,则添加另一个Favorite对象,因此现在有两个 Favorites将此类元素与用户链接。

修复逻辑

您可能只想else在该if部分从未执行过(即没有循环)的情况下执行该部分。我们可以使用for-else构造来做到这一点:

for items in userfav:
    if items.item == favitem:
        items.delete()
        break
else:
    new_entry = Favorite(item=favitem, user=request.user)

所以请注意,这里与循环中断else` 部分else处于同一级别,不会触发。for. And theis crucial, since this will make sure the

优化流程

但是我们太难了。我们可以简单地让 Django 执行过滤,并删除收藏夹。我们也可以filter(..)在查询集上item删除这些条目。如果没有删除条目,我们可以添加这样的Favorite条目:

def favorite_item (request, pk):
    favitem = get_object_or_404(Item, pk=pk)
    num, __ = Favorite.objects.filter(user=request.user, item=favitem).delete()
    if not num:
        new_entry = Favorite.objects.create(item=favitem, user=request.user)

    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

所以这里num将包含Favorite删除的条目数。如果它不为零,我们删除了一个或多个Favorite用户是的 s request.user,并且item是我们的favitem

如果num不为零,我们然后.create(..)一个新的Favorite.

约束Favorite模型

您还可以更好地约束您的Favorite模型。现在,看起来用户可以多次制作相同 Item内容。你最好使用它,以防止:Favorite unique_together

class Favorite(models.Model):

    item = ForeignKey(Item, on_delete=models.CASCADE)
    user = ForeignKey(User, on_delete=models.CASCADE)

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

当然,我在这里对Favorite模型的外观做了一些假设。然而,重要的部分是unique_together.

如果我们添加了这样的约束,我们知道对于 a.filter(user=..., item=...)总是最多有一个这样的元素。所以在那种情况下,逻辑就更简单了:

def favorite_item (request, pk):
    favitem = get_object_or_404(Item, pk=pk)
    try:
        Favorite.objects.get(user=request.user, item=favitem).delete()
    except Favorite.DoesNotExist:
        new_entry = Favorite.objects.create(item=favitem, user=request.user)

    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

推荐阅读