如何在Django页面中保存多个表单

时间:2017-06-15 21:26:05

标签: javascript django forms

我正在尝试在Django中制作投注应用。用户登录后,会有一个包含多个表单的页面,每个表单都负责保存匹配结果。每个表单需要两个整数输入(每个团队的目标数)。我希望在这些表单的末尾有一个保存按钮,以便在单击时,输入数据记录在数据库中。我有两个模型,Game和Bet。游戏负责存储游戏的实际结果,而Bet则负责记录用户预测。

class Game(models.Model):
    team1_name = models.CharField(max_length=100)
    team2_name = models.CharField(max_length=100)
    team1_score = models.IntegerField()
    team2_score = models.IntegerField()

class Bet(models.Model):
    user = models.ForeignKey(User)
    game = models.ForeignKey(Game)
    team1_score = models.IntegerField()
    team2_score = models.IntegerField()

这是主页

{% for game in games %}
<form action="../place_bet/" method="post">
  {% csrf_token %}
  <table>
    <tr>
      <th class="table-col"><label for="team1_score">{{ game.team1_name}}</label></th>
      <th class="table-col">{{ form.team1_score }}</th>
    </tr>
    <tr>
      <td class="table-col"><label for="team2_score">{{ game.team2_name}}</label></td>
      <td class="table-col">{{ form.team2_score }}</td>
    </tr>
  </table>
  <input type="submit" value="Submit" id="submit-button"/>
</form>
{% endfor %}

我的问题是如何在place_bet视图中捕获单击提交按钮时触发的不同表单的输入字段。

1 个答案:

答案 0 :(得分:2)

有关如何在Django上使用一个表单处理多个重复字段的详细答案,请阅读此答案历史记录。这将是关于在Django中从一个页面处理多种表单的良好实践的答案。

所以我们需要这样做,我们需要的是以下内容:

  1. 一个视图,它可以是基于类的或基于函数的,在这个例子中,我会使用基于类的,因为它很整洁。
  2. 提供此视图的网址,唯一特别之处是添加到其末尾的可选参数。
  3. 具有正确设置的模板,用于调用右视图功能。
  4. 您可以选择使用表单验证数据,但这不是必需的。
  5. 所以,首先,让我们创建视图。这将把问题分开,以提高可读性。

    from django.shortcuts import render, get_object_or_404
    from django.views import View
    from django.http import HttpResponseBadRequest
    
    class PlaceBet(View):
      template_name = 'place_bets.html'
      context = some_base_context_dict
    
      def get(self, request):
        # the user is requesting the game list
        self.context['games'] = Game.objects.all()
        return render(request, self.template_name, self.context)
    
      def post(self, request, game_id=None):
        # the user is submitting one of game's predictions
        if not game_id:
          return HttpResponseBadRequest('hey, send a game id, you fool!')
        game = get_object_or_404(Game, pk=game_id)
        # here you can use a Form to validate the data, but hey,
        # do your homework
        bet = Bet.objects.create(user=request.user, game=game, 
                                 team1_score=request.POST.get('team1_score'),
                                 team2_score=request.POST.get('team2_score'))
        # bet is saved at this point so now we can now take the user
        # elsewhere or i dunno, the same page...
        self.context['games'] = Game.objects.all()
        self.context['new_bet'] = bet
        response = render(request, self.template_name, self.context)
        # it's good practice to say you created something
        response.status_code = 201
        return response
    

    现在,网址也需要一些工作,你传递一个参数,所以......

    urlpatterns = [
      url(r'^place_bet$', PlaceBet.as_view()),
      url(r'^place_bet/(?P<game_id>[^/.]+)', PlaceBet.as_view(), name='place-bet') #name parameter, very important for the future...
    ]
    

    您的模板几乎是正确的,但它需要一些工作:

    {% for game in games %}
    <!-- the action now points to the URL by name, and passes the game_id -->
    <form action="{% url 'place-bet' game.pk %}" method="POST">
      {% csrf_token %}
      <table>
        <tr>
          <th class="table-col">
            <label for="team1_score">{{ game.team1_name}}</label>
          </th>
          <th class="table-col">
            <!-- you need something to submit -->
            <input type="number" name="team1_score" value="{{ game.team1_score }}">
          </th>
        </tr>
        <tr>
          <td class="table-col">
            <label for="team2_score">{{ game.team2_name}}</label>
          </td>
          <td class="table-col">
            <input type="number" name="team2_score" value="{{ game.team2_score }}">
          </td>
        </tr>
      </table>
      <input type="submit" value="Submit" id="submit-button"/>
    </form>
    {% endfor %}
    

    就是这样,现在当你按下提交按钮时,浏览器会使用编码游戏ID的动作URL将POST数据发送到视图的post方法,所以没有错误的余地。

    这段代码可以进行很多改进,但它会帮助你。