Django 外键表单保存
Django foreign key form save
编辑:我已经解决了这个问题(在 Whosebug 和 IRC 的帮助下,但我必须等待两天才能将这个问题标记为已解决。请参阅下面的回复以查看解决方案!
我目前正在制作一个 'IMDB' 克隆版供我和我的朋友使用。这个想法是我们每个人都有一个帐户,可以提交新电影或对已经提交的电影进行投票。这些电影按评级排序,用户可以访问详细视图以查看各个评论。
为了实现这一点,我在 models.py 中使用外键 - 一个用于电影条目(包含导演、标题等信息),一个用于个人投票。后者使用外键获取电影标题和提交评论的用户。
然而,在测试提交评论的表单时,我遇到了 'NOT NULL constraint failed: list_vote.voter_id_id' 错误。浏览错误页面时,我发现外键值没有提交到数据库
params: [None, None, 9.0]
query: ('INSERT INTO "list_vote" ("movie_id_id", "voter_id_id", "rating") VALUES (?, ' '?, ?)')
self <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x7f77b8907dc8>
然而,当我在执行 'post.save()' 命令时浏览本地变量的错误页面时,似乎缺少变量
entry: <Entry: Starwars 4>
form: <VoteForm bound=True, valid=True, fields=(rating)>
movie_id: 'Starwars 4'
post: <Vote: Vote object>
request: <WSGIRequest: POST '/vote/starwars-4/'>
slug: 'starwars-4'
voter_id : <SimpleLazyObject: <User: admin>>
如果我将“movie_id”和“user_id”值添加到我的模型中(在 'fields' 变量中),该表单实际上可以工作。 (虽然这不是我想要的,因为这个数据库中可能有数百部电影,这使得选择变得相当困难。现在,任何用户都可以假装成任何人)
我可能遗漏了一些非常明显的东西,但对于我来说,我无法弄清楚我做错了什么。模型、表格等都基于 Django_girls 教程(他们工作的地方)和 'Hello WebApp' 书(尽管本书中没有使用外键)
有谁知道我在这里做错了什么?
这些是使用的模型:
class Entry(models.Model):
movie = models.CharField(max_length=255)
director = models.CharField(max_length=255)
total_votes = models.IntegerField(default=0)
rating = models.FloatField(default=0)
length = models.IntegerField(default=0)
year = models.IntegerField(default=0)
added_by = models.ForeignKey(User)
slug = models.SlugField(unique=True)
def __str__(self):
return self.movie
########################
Vote-model:
########################
class Vote(models.Model):
class Meta:
unique_together = (('voter_id','movie_id'),)
movie_id = models.ForeignKey(Entry)
voter_id = models.ForeignKey(User)
rating = models.FloatField(validators=[MinValueValidator(0), MaxValueValidator(10)])
这是我的form.py:
class VoteForm(ModelForm):
class Meta:
model = Vote
fields = ('rating',)
这是view.py的相关函数:
def lets_vote(request, slug):
entry = Entry.objects.get(slug=slug)
if request.method == "POST":
form = VoteForm(request.POST)
if form.is_valid():
voter_id = request.user
movie_id = Entry.objects.get(slug=slug).movie
post = form.save(commit=False)
post.save()
return redirect('/movies/')
else:
form = VoteForm()
return render(request, 'list/lets_vote.html', {'entry':entry, 'form': form})
最后但同样重要的是:来自 html 页面的投票表:
<form role="form" action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
{% endblock %}
我也在 Django IRC 上发布了这个问题,那里有人帮我解决了这个问题!
我原来犯了两个错误:
- 我在模型中添加了“_id”。这已经自动完成了,所以我数据库中的变量实际上被称为 'movie_id_id'。我已经删除了多余的“_id”。
下一行中的“.movie”是不必要的。
post.movie = Entry.objects.get(slug=slug).movie
正确的工作视图如下:
def lets_vote(request, slug):
entry = Entry.objects.get(slug=slug)
form = VoteForm(request.POST)
if request.method == "POST":
if form.is_valid():
post = form.save(commit=False)
post.voter = request.user
post.movie = Entry.objects.get(slug=slug)
post.save()
return redirect('/movies')
我只需要实际实例,但@Alasdair 的其余部分他的建议是正确的。
谢谢来自 IRC 的@Alasdair 和 Flobin!
编辑:我已经解决了这个问题(在 Whosebug 和 IRC 的帮助下,但我必须等待两天才能将这个问题标记为已解决。请参阅下面的回复以查看解决方案!
我目前正在制作一个 'IMDB' 克隆版供我和我的朋友使用。这个想法是我们每个人都有一个帐户,可以提交新电影或对已经提交的电影进行投票。这些电影按评级排序,用户可以访问详细视图以查看各个评论。
为了实现这一点,我在 models.py 中使用外键 - 一个用于电影条目(包含导演、标题等信息),一个用于个人投票。后者使用外键获取电影标题和提交评论的用户。
然而,在测试提交评论的表单时,我遇到了 'NOT NULL constraint failed: list_vote.voter_id_id' 错误。浏览错误页面时,我发现外键值没有提交到数据库
params: [None, None, 9.0]
query: ('INSERT INTO "list_vote" ("movie_id_id", "voter_id_id", "rating") VALUES (?, ' '?, ?)')
self <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x7f77b8907dc8>
然而,当我在执行 'post.save()' 命令时浏览本地变量的错误页面时,似乎缺少变量
entry: <Entry: Starwars 4>
form: <VoteForm bound=True, valid=True, fields=(rating)>
movie_id: 'Starwars 4'
post: <Vote: Vote object>
request: <WSGIRequest: POST '/vote/starwars-4/'>
slug: 'starwars-4'
voter_id : <SimpleLazyObject: <User: admin>>
如果我将“movie_id”和“user_id”值添加到我的模型中(在 'fields' 变量中),该表单实际上可以工作。 (虽然这不是我想要的,因为这个数据库中可能有数百部电影,这使得选择变得相当困难。现在,任何用户都可以假装成任何人)
我可能遗漏了一些非常明显的东西,但对于我来说,我无法弄清楚我做错了什么。模型、表格等都基于 Django_girls 教程(他们工作的地方)和 'Hello WebApp' 书(尽管本书中没有使用外键)
有谁知道我在这里做错了什么?
这些是使用的模型:
class Entry(models.Model):
movie = models.CharField(max_length=255)
director = models.CharField(max_length=255)
total_votes = models.IntegerField(default=0)
rating = models.FloatField(default=0)
length = models.IntegerField(default=0)
year = models.IntegerField(default=0)
added_by = models.ForeignKey(User)
slug = models.SlugField(unique=True)
def __str__(self):
return self.movie
########################
Vote-model:
########################
class Vote(models.Model):
class Meta:
unique_together = (('voter_id','movie_id'),)
movie_id = models.ForeignKey(Entry)
voter_id = models.ForeignKey(User)
rating = models.FloatField(validators=[MinValueValidator(0), MaxValueValidator(10)])
这是我的form.py:
class VoteForm(ModelForm):
class Meta:
model = Vote
fields = ('rating',)
这是view.py的相关函数:
def lets_vote(request, slug):
entry = Entry.objects.get(slug=slug)
if request.method == "POST":
form = VoteForm(request.POST)
if form.is_valid():
voter_id = request.user
movie_id = Entry.objects.get(slug=slug).movie
post = form.save(commit=False)
post.save()
return redirect('/movies/')
else:
form = VoteForm()
return render(request, 'list/lets_vote.html', {'entry':entry, 'form': form})
最后但同样重要的是:来自 html 页面的投票表:
<form role="form" action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
{% endblock %}
我也在 Django IRC 上发布了这个问题,那里有人帮我解决了这个问题!
我原来犯了两个错误:
- 我在模型中添加了“_id”。这已经自动完成了,所以我数据库中的变量实际上被称为 'movie_id_id'。我已经删除了多余的“_id”。
下一行中的“.movie”是不必要的。
post.movie = Entry.objects.get(slug=slug).movie
正确的工作视图如下:
def lets_vote(request, slug):
entry = Entry.objects.get(slug=slug)
form = VoteForm(request.POST)
if request.method == "POST":
if form.is_valid():
post = form.save(commit=False)
post.voter = request.user
post.movie = Entry.objects.get(slug=slug)
post.save()
return redirect('/movies')
我只需要实际实例,但@Alasdair 的其余部分他的建议是正确的。 谢谢来自 IRC 的@Alasdair 和 Flobin!