【问题标题】:using key presses instead of buttons in django forms在 django 表单中使用按键而不是按钮
【发布时间】:2014-09-19 22:56:26
【问题描述】:

我有一个网站,允许输入文本、对条目进行投票以及投票条目的实时表格: http://www.highscore.a2hosted.com/index/

这是用 django 编码的。我设法在一页上获得了一个文本条目和一个投票表格。

文本输入: 当按下回车键时,文本条目会向数据库 (sqlite3) 添加一个新条目。一些javascript将输入绑定到按键以发送到views.py,它使用GET来添加文本和当前日期时间。没有使用任何表单,并且在 js 中重新加载了位置。

投票表格 投票表单是 POST 方法,您有两个提交按钮来向上或向下投票显示的文本。显示的文本是从 html 中的“for 循环”访问的。这是在页面刷新时从views.py 更新为最新的未投票文本。

在views.py 的投票函数中,向上或向下按钮的名称以及被投票的条目的id 被发送。投票增加或减少条目的分数,保存并刷新页面。

物理安装 我的下一步是构建一个使用 Web 架构的物理安装。最终安装不会在一个页面上,因此会有一个投票站和一个入口站。我将使用街机按钮进行输入和投票。

街机按钮 > 操纵杆编码器 > Joy2Key 映射器 我将街机按钮连接到 ZeroDelay 操纵杆编码器,并让 Joy2Key 运行,按钮映射到 13(输入)38(向上箭头)和 40(向下箭头)。

文本输入一切正常(操纵杆按钮映射到输入按钮 13)。

我遇到问题的地方是尝试获取使用 django 表单的密钥。 由于投票使用表单,django 期望在按钮区域中单击鼠标。我正试图解决这个问题。我得到的最接近的方法是在投票表单中放置一个多余的文本输入框来捕获关键活动。

当该框处于活动状态时,我可以按下映射到向上箭头的按钮,并在我的命令提示符中查看一些 POST 反馈(但它还没有发送投票)。如果我点击文本输入框,我可以按下映射到输入按钮的按钮,并在我的命令提示符和成功的文本输入中获得 GET 反馈。

所以我的问题是.....没有大量外部库或花哨的 Gamepad API 编码,是否有一种简洁的方法可以让 django 表单按钮仅通过键盘按下工作?如果需要是一个活动框,这可以隐藏和全屏吗? (我已经尝试过了,但没有运气)

【问题讨论】:

    标签: javascript jquery python django forms


    【解决方案1】:

    好的,这就是我所做的。

    在新的voting.html 中,我有这段代码来捕获操纵杆映射到的箭头按钮:

    <div id="Vote" class = "high">
      <div style="text-align: center">
      {% for entry in voting_entry_list %} 
        <li><a href="/entries/{{ entry.id }}/">{{ entry.text }}&nbsp{{ entry.score }}</a></li>
        <p>
        <input type="submit" id="voteid" name='voteid' value="{{ entry.id }}" autofocus value="" onfocus="this.value = this.value;" class = "transparent"/>
              <script>
                $(document).ready(function() {
                  $("#voteid").bind("keydown", function(e) { //input type=id above
                    if (e.keyCode == 38) {
                      var text = $("#voteid").val();        
                      var args = {'voteid':text};       
                      $.get("/voteup/", args).done(function(data) {
                        console.log("message: " + data);
                        location.reload();  
                      });
                    return false;
                    }
                    if (e.keyCode == 40) {
                      var text = $("#voteid").val();        
                      var args = {'voteid':text};       
                      $.get("/votedown/", args).done(function(data) {
                        console.log("message: " + data);
                        location.reload();  
                      });
                    return false;
                    }       
                  });
                });     
              </script>
      {% endfor %}
      </div>
    </div>
    

    然后在 views.py 中,我使用 GET 而不是 POST 来捕获赞成票或反对票:

    def voting(request):   
    context = {
      'latest_entry_list': Entry.objects.order_by('-pub_date')[:10], # simple sorting by datetime, latest first, 10 items
      'high_entry_list': Entry.objects.order_by('-score','-pub_date')[:10], # simple sorting by score high to low, 10 items
      'high_entry': Entry.objects.order_by('-score','-pub_date')[:1], # simple sorting by score high to low, 10 items
      'low_entry_list': Entry.objects.order_by('score','-pub_date')[:10], # simple sorting by score low to high, 10 items
      'voting_entry_list': Entry.objects.unvoted_or_random(), # actually one item, command from extended object manager
    }
    return render(request, 'entries/voting.html', context); # returns when vote is accessed
    
    def voteup(request):
    voting_id = request.GET.get('voteid') # voting id number is brought in as var
    if request.method=='GET': #always polling, when get votes, save and redirect to /index to refresh
        v = Entry.objects.get(pk=voting_id) # get by voting id var
        v.score +=1 # add one to score for voteup button
        v.voted=True # set voted boolean to true
        v.save() # explicit save, as is not saved with change above
    else:
        pass
    return HttpResponse('done') # Only on console 
    
    def votedown(request):
    voting_id = request.GET.get('voteid') # voting id number is brought in as var
    if request.method=='GET': #always polling, when get votes, save and redirect to /index to refresh
        v = Entry.objects.get(pk=voting_id) # get by voting id var
        v.score -=1 # add one to score for voteup button
        v.voted=True # set voted boolean to true
        v.save() # explicit save, as is not saved with change above
    else:
        pass
    return HttpResponse('done') # Only on console
    

    这似乎避免了表单和按键的任何问题。由于它在一个单独的投票页面上,透明的虚拟提交按钮使该选择在刷新时处于活动状态,而不是当它们在同一页面上时的文本输入框。我可以从voting_entry_list 中访问已排序的条目,并使用单独的js 脚本和views.py 请求对每个按钮进行投票。

    我的目标是使用基本的 django 和 js 来完成这项工作,对安装大量库或编写额外的 gamepad.api 状态和轮询没有信心,所以工作完成了!

    目前这只是一种组合,但看起来很稳固。将来,我可能会尝试通过按键开关来简化它,如果这是一个安全问题,我可能会尝试使用 POST 而不是 GET。

    【讨论】:

      猜你喜欢
      • 2020-08-17
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 2011-05-25
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      相关资源
      最近更新 更多