我正在为一个类编写Django程序。我知道错误与外键分配有关,但我不明白我的逻辑缺陷在哪里。
以下是两个相关模型:
@UI.facet: [{
label : 'General Information',
id : 'GeneralInfo',
isSummary:true,
purpose: #STANDARD,
type : #COLLECTION,
position: 10
},
{
label: 'Basic Data',
id : 'BasicData',
purpose: #STANDARD,
parentId : 'GeneralInfo',
type : #FIELDGROUP_REFERENCE,
targetQualifier : 'BasicData',
position: 20
}]
class listing(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
url = models.URLField(default="", null=True, max_length=100)
category = models.CharField(default="", max_length=50)
user_name = models.CharField(max_length=100)
date = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
min_bid = models.DecimalField(max_digits=8, decimal_places=2)
class watchlist(models.Model):
item_id = models.IntegerField(null=False)
user_id = models.IntegerField(null=False)
#item_id = models.ForeignKey("auctions.listing", on_delete=models.CASCADE, related_name="item_watchlist")
#user_id = models.ForeignKey("auctions.User", on_delete=models.CASCADE, related_name="user_watchlist")
中的最后两行已被注释掉,从而使代码可以正常工作。但是,我想了解如何按照我的初衷进行这项工作。如下所示:(以下代码在对象创建带有watchlist Class
的节时失败)
ValueError, cannot assign <value>: item_id must be an instance of listings.
我的假设是,在监视列表模型上创建外键会将选择限制为列出PK 。删除对象没问题,它工作正常。即使我可以查询列表,并且确实存在ID为7的对象,但创建一个条目的Item_id为7的对象也未能添加到监视列表中:
@login_required
def item_listing(request, id):
itemID = id
# GET call coming in from clicking a title link
if request.method == "GET":
item = listing.objects.filter(id=id)
# Check if the item is on the user's watchlist
if watchlist.objects.filter(item_id=id, user_id=request.user.id).exists():
watch = True
else:
watch = False
return render(request, "auctions/ItemPage.html", {
"item": item,
"name": item[0].title,
"url": item[0].url,
"description": item[0].description,
"user_name": item[0].user_name,
"price": item[0].min_bid,
"category": item[0].category,
"watch": watch
})
# POST call coming in from clicking the watchlist button
if request.method == "POST":
q = request.POST.get('wl')
# Remove from watchlist. Delete entry in database.
if q == "Remove from Watchlist":
watchlist.objects.filter(item_id=id, user_id=request.user.id).delete()
# Add to watchliset. Create entry.
else:
watchlist.objects.create (
item_id=id,
user_id=request.user.id
)
# Redirect back to thet page
pathname = "/" + str(itemID)
return redirect(pathname)
因此,我认为我对ForiegnKey的理解和使用存在缺陷。我将如何正确执行此操作?
此外,如果我的格式设置已关闭,我深表歉意,这是我第一次在这里发布。
答案 0 :(得分:0)
我认为这是一个很常见的错误。创建ForeignKey
字段时,它充当实际数据库外键关系的抽象。这意味着(在您的情况下)调用watchlist.item_id
不会返回id
,而是实际的listing
对象。创建对象时是相同的。
使用实际项目而不是其ID的整数值创建监视列表:
watchlist.objects.create (
item_id=item,
user_id=request.user.id
)
我不确定将键而不是实例传递给模型的filter方法是否有效,但是最好也将实际对象传递给模型:
watchlist.objects.filter(item_id=item, user_id=request.user)
这看起来有些奇怪:虽然您可能习惯于将外键称为item_id,但最好以实际关系命名外键。因此,在这种情况下,您应该将item_id
类中的watchlist
更改为item
。
此外,Django类应使用大写字母编写,因此您的类应如下所示:
class Listing(models.Model):
...
class WatchList(models.Model):
item = models.ForeignKey("auctions.listing", on_delete=models.CASCADE, related_name="item_watchlist")
user = models.ForeignKey("auctions.User", on_delete=models.CASCADE, related_name="user_watchlist")
,然后您的代码当然应该更改为:
WatchList.objects.create (
item=item,
user=request.user.id
)
和:
WatchList.objects.filter(item=item, user=request.user)