无法保存到数据库。提交表单会刷新表单页面

时间:2012-01-20 22:36:26

标签: python mysql django

我正在尝试继承player_id并保存到Stakes表,引用该player_id,这是Stakes表的外键。但是,我不知道该怎么做。我已经编辑了我的views.py以反映下面的两个答案,但它似乎仍然刷新表单而不保存到数据库。我唯一能想到的是这是由于DateTimeField。但是,我正在以确切的格式使用数据库中的复制/粘贴日期,所以我怀疑是不是。

Models.py

class Player(models.Model):
    user_name = models.CharField(max_length=200)
    real_name = models.CharField(max_length=200)
    SITE_CHOICES = (
        ('FTP', 'Full Tilt Poker'),
        ('Stars', 'Pokerstars'),
        ('UB', 'Ultimate Bet'),
    )
    site_played = models.CharField(max_length=5, choices=SITE_CHOICES)

class Stakes(models.Model):
    player = models.ForeignKey(Player)
    stakes = models.CharField(max_length=200)
    amount_won = models.DecimalField(max_digits=12, decimal_places=2)
    last_play_date = models.DateTimeField('Date Last Updated')

Views.py

def new_stake(request, player_id):
if request.method == 'POST': # If the form has been submitted
    player = get_object_or_404(Player, pk=player_id)
    form = StakeForm(request.POST) # A form bound to the POST data
    if form.is_valid(): # All validation rules pass
        # Process the data in form.cleaned_data
        # ...
        stakes = form.cleaned_data['stakes']
        amount_won = form.cleaned_data['amount_won']
        last_played_date = form.cleaned_data['last_played_date']
        stakes_new = Stakes(player = player, 
                stakes = stakes,
                amount_won = amount_won,
                last_played_date = last_played_date)
        stakes_new.save()
        return HttpResponseRedirect('/stakeme/stake_added/') # redirect after POST
else:
    form = StakeForm() # An unbound form
return render_to_response('stakeme/new_stake.html',
                                       context_instance=RequestContext(request))

new_stake.html

<h1> New Play </h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post">
{% csrf_token %}
    Stake Played: <input type="text" name="stakes" id="stakes"/><br>
    Amount Won/Lost: <input type="text" name="amount_won" id="amount_won"/><br>
    Date/Time of play: <input type="text" name="last_play_date" id="last_play_date"/><br><br>
<input type="submit" value="Add New Play" />
</form>

urls.py

(r'^(\d+)/new_stake/$', 'new_stake', name='new_stake' ),

forms.py

class StakeForm(forms.Form):
    player_id = forms.IntegerField()
    stakes = forms.CharField(max_length=200)
    amount_won = forms.IntegerField()
    last_play_date = forms.DateTimeField()

任何帮助将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:0)

为什么你不能这样做:

(r'^(\d+)/new_stake/$', 'new_stake', name='new_stake' ),

在验证表单时,最有可能出现错误。您可能希望返回视图以查找以下行中的错误:

def new_stake(request, player_id):
    if request.method == 'POST': # If the form has been submitted
        form = StakeForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            stakes = form.cleaned_data['stakes']
            amount_won = form.cleaned_data['amount_won']
            last_played_date = form.cleaned_data['last_played_date']
            stakes_new = Stakes(player_id = player_id, 
                        stakes = stakes,
                        amount_won = amount_won,
                        last_played_date = last_played_date)
            stakes_new.save()
            return HttpResponseRedirect('/stakeme/stake_added/') # redirect after POST

        else:
            player = get_object_or_404(Player, pk=player_id)
            player.form = StakeForm(request.POST)
            return render_to_response('stakeme/new_stake.html', {'player': player}
                                           context_instance=RequestContext(request))
    else:
        player = get_object_or_404(Player, pk=player_id)
        player.form = StakeForm() # An unbound form
        return render_to_response('stakeme/new_stake.html', {'player': player}
                                           context_instance=RequestContext(request))

答案 1 :(得分:0)

你应该这样做:

(注意if request.method下面的新行,我编辑了“stakes_new”行)

if request.method == 'POST': # If the form has been submitted
    player = get_object_or_404(Player, pk=player_id)
    form = StakeForm(request.POST) # A form bound to the POST data
    if form.is_valid(): # All validation rules pass
        # Process the data in form.cleaned_data
        # ...
        stakes = form.cleaned_data['stakes']
        amount_won = form.cleaned_data['amount_won']
        last_played_date = form.cleaned_data['last_played_date']
        stakes_new = Stakes(player = player, 
                    stakes = stakes,
                    amount_won = amount_won,
                    last_played_date = last_played_date)
        stakes_new.save()

答案 2 :(得分:0)

这个答案是由另一个网站给我的。他不想在此重新发布,但我会复制/粘贴以接受答案并供将来参考。

在视图中,即使未发送POST数据,也应调用查找player_id。这可确保您在URL中存在无效的player_id时获得404。我只是将这行代码移到IF语句之上。

尽可能不在模板中定义表单。当表单无效时,它可以避免丢失错误消息等有用的内容。 Django提供了一些漂亮的工具来为您自动生成表单HTML。我将表单更新为如下所示。注意:我在这里使用'form.as_table',但如果您不喜欢HTML输出作为表格,还有一些其他有用的方法,如'as_p'。这是新的new_stake.html:

<h1> New Play </h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post">
    {% csrf_token %}
    <table>{{form.as_table}}</table>
    <input type="submit" value="Add New Play" />
</form>

如果form_id实际上不是表单的一部分,则从表单类中删除它(或者更好,将其设置为隐藏字段)。此外,您可能应该在此处使用ModelForm,它将在收到POST数据后为您自动填充表单元素。但是,我没有在这里做出这样的评价。我所做的是从FORMS.py中的表单中删除player_id行,因为它已经在URL中,并且似乎是你想要从中获取它(而不是如上所述的隐藏输入)。

class StakeForm(forms.Form):
    stakes = forms.CharField(max_length=200)
    amount_won = forms.IntegerField()
    last_play_date = forms.DateTimeField()

此时,您应该开始看到您更接近获得工作表单了。您看到的问题主要是您的表单未通过is_valid()检查,如果您查看代码,则会再次显示该表单。为了让事情看起来更糟,你从来不知道表单是无效的,因为你设计了自己的表单HTML,但不包含错误消息。一旦我在模板中使用{{form}}而不是在原始html中使用自定义表单代码,此修复就变得更加明显。

第二个音符,你错过了将last_play_date拼写为last_played_date。它可能按照您的方式工作,但为了保持类似的命名约定,我将其重命名为last_play_date以匹配模型。

关于views.py的最后说明。您应该尝试不将URL defiend重定向为字符串。 URL有一个很好的功能,可以让你命名。您可以使用reverse()函数执行“reverse('stake_added')”查找。

最终的VIEWS.py看起来像这样:

def new_stake(request, player_id):
    vars = {}
    player = get_object_or_404(Player, pk=player_id)
    if request.method == 'POST': # If the form has been submitted
        form = StakeForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            stakes = form.cleaned_data['stakes']
            amount_won = form.cleaned_data['amount_won']
            last_play_date = form.cleaned_data['last_play_date']
            stakes_new = Stakes(player=player, stakes=stakes,
                amount_won=amount_won, last_play_date=last_play_date)
            stakes_new.save()
            return HttpResponseRedirect(reverse('stake_added')) # redirect after POST
    else:
        form = StakeForm() # An unbound form
    # Package up some variables to return
    vars['player'] = player
    vars['form'] = form
    context = RequestContext(request)
    return render_to_response('stakeme/new_stake.html', vars, context_instance=context)

好的方法是,这是最终的URLS.py:

urlpatterns = patterns('',
    url(r'^(\d+)/new_stake/$', new_stake, name='new_stake'),
    url(r'^stake_added/$', direct_to_template, {'template':'stakeme/stake_added.html'}, name="stake_added"),
    url(r'^admin/', include(admin.site.urls)),
)