【问题标题】:How to save multiple forms in on page in Django如何在Django的页面上保存多个表单
【发布时间】:2017-06-15 21:26:05
【问题描述】:

我正在尝试在 Django 中制作一个投注应用程序。用户登录后,会出现一个包含多个表单的页面,每个表单负责保存匹配结果。每个表格都有两个整数输入(每个团队的目标数)。我希望在这些表单的末尾有一个保存按钮,以便在单击时将输入数据记录在数据库中。我有两个模型,游戏和投注。 Game负责存储游戏的实际结果,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 视图中捕获不同表单的输入字段。

【问题讨论】:

  • 听起来你想要一个包含更多字段的表单而不是多个表单。
  • @CarsonCrane 我也想过这个问题,但是你不认为当预测的比赛数量变大时事情会失控吗?

标签: javascript django forms


【解决方案1】:

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

所以有一个配方,我们需要的是以下内容:

  1. 一个视图,它可以是基于类的,也可以是基于函数的,在这个例子中,我将使用基于类,因为它很整洁。
  2. 提供此视图的 URL,唯一的特殊之处是添加到其末尾的可选参数。
  3. 具有正确设置的模板,用于调用正确的视图函数。
  4. 您可以选择使用表单来验证数据,但这不是必需的。

所以,首先,让我们创建视图。这会将关注点分开以提高可读性。

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

现在,Urls 也需要一些工作,您正在传递一个参数,所以...

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 %}

就是这样,现在当你按下提交按钮时,浏览器会将 POST 数据发送到视图的post 方法,使用一个对游戏 ID 进行编码的操作 URL,因此没有出错的余地。

这段代码可以改进很多,但它会让你继续前进。

【讨论】:

  • 感谢您的详尽回答,您能否详细说明一下良好做法?干杯
  • 你知道,也许是因为我看错了问题,你在每个循环中重复提交按钮,所以你每次提交一对字段。我会修正我的答案!
猜你喜欢
  • 2015-01-30
  • 2018-03-05
  • 2011-08-16
  • 1970-01-01
  • 2019-09-05
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 2020-04-22
相关资源
最近更新 更多