【发布时间】:2016-01-03 19:41:59
【问题描述】:
我正在构建一个 Django 站点来共享 Python 游戏的代码,但我在将每个游戏与特定用户关联时遇到了麻烦。我正在尝试通过将用户用作ForeignKey 来做到这一点,我认为这是正确的方法,但是如果不使用一些奇怪的 hack(比如传递用户),我无法让用户实际插入数据库作为字符串到隐藏的user 字段中,这是完全不安全的并且会导致其他问题。)
我的Game 类如下所示:
class Game(models.Model):
user = models.ForeignKey(User, blank=True)
title = models.CharField(max_length=256)
image = models.ImageField(upload_to='games')
description = models.CharField(max_length=256)
requirements = models.CharField(max_length=256)
code = models.CharField(max_length=256000)
def __unicode__(self):
return self.title
添加游戏的表单:
class GameForm(forms.ModelForm):
image = forms.ImageField(required=False)
code = forms.CharField(widget=PagedownWidget(show_preview=True))
class Meta:
model = Game
fields = ('user','title','image','description','requirements','code')
User.game = property(lambda u: Game.objects.get_or_create(user=u)[0])
我在我的addgame.html 模板中创建了此表单的自定义版本:
<form action="/userprofile/addGame/" method="post">{% csrf_token %}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}
<br>
{{ field }}
<br><br>
</div>
{% endfor %}
<input type="submit" value="Save">
</form>
我的视图如下所示:
@login_required
def add_game(request):
user = request.user
error_message = None
if request.method == 'POST':
form = GameForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.uploader = request.user
form.save()
return HttpResponseRedirect('/userprofile')
else:
error_message = "Invalid Input"
else:
form = GameForm()
args = {}
args.update(csrf(request))
args['user'] = user
args['form'] = form
args['error_message'] = error_message
return render_to_response('addgame.html', args)
但是,我收到以下错误:
无法分配无:“Game.user”不允许空值。
我意识到 User 实例尚未传递到表单中,因此我收到“不应为空”错误,但我不知道如何正确地将 User 实例传递给形式。我已经查看了几个关于这个确切问题的问题,例如this,但我仍然无法将User 成功传递到表单中。
【问题讨论】:
-
这通常在视图中完成。您可以将其添加到您的问题中吗?
-
必须去,但基本工作流程:视图实例化表单,然后视图触发表单验证,然后视图在
form.instance上设置附加字段,然后视图保存表单。 (作为替代方案,视图可以先保存,commit=False,然后设置其他字段,然后保存模型)。 -
你的权利,完全忘了包括那个。刚加进去。
-
我无法理解你的 monkeypatched
User.game属性的意义。你有一个从游戏到用户的 FK,所以一个用户可以有多个游戏;如果您只想要一个,请使用 OneToOneField。 FK 和 OneToOneField 都已经提供了一个反向访问器来从 User 访问 Game。 -
是的,我很确定这完全没有意义 :) ...我不久前遇到了一个错误,该错误只能通过包含该行来修复,但现在没有它也可以正常工作,所以我已经删除了。
标签: python django foreign-keys