【问题标题】:Show more data button in a list of posts django在帖子列表中显示更多数据按钮 django
【发布时间】:2021-10-17 11:22:24
【问题描述】:

我正在使用 Django 练习使用 Riot API 创建一个包含英雄联盟数据的网络。有一个页面,您可以在其中查看搜索到的玩家的游戏历史。我正在尝试创建一个按钮,在同一页面上显示游戏的深入数据而无需重新加载,因为如果我首先尝试加载每个游戏的数据,加载页面需要很长时间。

我还没有做太多关于前端的事情,所以目前看起来是这样的:

views.py 的相关部分如下所示:

def user_info(request, server, summoner_name, template='riot/user-profile.html'):

    account_id = user_account_info['accountId']

    games_list = api_interaction.get_past_games(server, account_id)

    champ_json = services.load_champ_json_session(request)

    game_summary_list = services.get_game_summary_list(games_list, champ_json)

    context = {
        'game_summary_list': game_summary_list,
        'user_account_info': user_account_info, 
        'summoner_stats': summoner_stats 
    }

    if ('load') in request.POST:
        gameId = (request.POST['load'])
        
        game_data = api_interaction.game_summary(server, gameId, champ_json)
        context['game_data'] = game_data
        return render(request, template, context)

    else:
        return render(request, template, context)

基本上我现在拥有的是按钮提交一个表单,在views.py中,如果提交了一个表单,它将处理一些数据并返回一个额外的python字典。然后在我的模板中,我有一个如下所示的 div:

{% for game in game_summary_list %}
<span class="anchor" id="{{forloop.counter}}"></span>
<div class="container" style="border:1px solid rgb(64, 97, 71);">
    <br>
    <h4><a href="/{{user_account_info.server}}/{{user_account_info.name}}/{{game.champion_name}}">{{ game.champion_name }}</a> {{game.position}} {{game.date}} {{ game.game_id}}</h4>

    <form action="#{{forloop.counter}}" method="post">
    {% csrf_token %}
    <button name="load" type="submit" value="{{game.game_id}}" class="btn btn-info">Show game summary</button>
    </form>
    <br>
    
    <div id="load_more">
        {% if game_data.success %}
        {% if game_data.game_id == game.game_id %}
            <table class="table table-bordered">
            <thead>
                <tr>
                    <th scope="col">Game ID</th>
                    <th scope="col">Server</th>
                    <th scope="col">When</th>
                    <th scope="col">Duration</th>
                    <th scope="col">Game Mode</th>
                    <th scope="col">Patch</th>
                </tr>
            </thead>
    
            <tbody>
                <tr>
                    <td>{{ game_data.gameId }}</td>
                    <td>{{ game_data.platformId }}</td>
                    <td>{{ game_data.gameCreation }}</td>
                    <td>{{ game_data.gameDuration }}</td>
                    <td>{{ game_data.gameMode }}</td>
                    <td>{{ game_data.gameVersion }}</td>
                </tr>
            </tbody>
    
            <thead>
                <tr>
                    <th scope="col">{{ game_data.teams.0.win }} (Blue Team)</th>
                    <th scope="col">Rank</th>
                    <th scope="col">KDA</th>
                    <th scope="col">Damage</th>
                    <th scope="col">CS</th>
                    <th scope="col">Vision Score</th>
                
                </tr>
            </thead>
            
            <tbody>
                {% for player in game_data.participants|slice:":5" %}
                <tr >
                    <td>{{ player.champion_name }}/<a href="/{{user_account_info.server}}/{{player.summoner_name}}"> {{ player.summoner_name }}</a></td>
                    <td>{{ player.tier }}</a></td>
                    <td>{{ player.stats.kills }}/{{ player.stats.deaths }}/{{ player.stats.assists }}</td>
                    <td>{{ player.stats.totalDamageDealtToChampions }}</td>
                    <td>{{ player.stats.totalMinionsKilled }}</td>
                    <td>{{ player.stats.visionScore }}</td>
                </tr>
                {% endfor %}
            </tbody>
    
            <thead>
                <tr>
                    <th scope="col">{{ game_data.teams.1.win }} (Red Team)</th>
                    <th scope="col">Rank</th>
                    <th scope="col">KDA</th>
                    <th scope="col">Damage</th>
                    <th scope="col">CS</th>
                    <th scope="col">Vision Score</th>
                
                </tr>
            </thead>
            
            <tbody>
                {% for player in game_data.participants|slice:"5:" %}
                    <tr>
                    <td>{{ player.champion_name }}/<a href="/{{user_account_info.server}}/{{player.summoner_name}}"> {{ player.summoner_name }}</a></td>
                    <td>{{ player.tier }}</a></td>
                    <td>{{ player.stats.kills }}/{{ player.stats.deaths }}/{{ player.stats.assists }}</td>
                    <td>{{ player.stats.totalDamageDealtToChampions }}</td>
                    <td>{{ player.stats.totalMinionsKilled }}</td>
                    <td>{{ player.stats.visionScore }}</td>
                    </tr>
                {% endfor %}
            </tbody>
            </table>
            <br>
        {% endif %}
        {% endif %}
    </div>
</div>
<br>

{% endfor %}

所以当按下按钮时,页面将如下所示:

虽然它有效,但这个过程的问题是当用户单击“显示游戏摘要”按钮时页面会重新加载。我通过为每个游戏的每个 div 添加一个 id 并将表单重定向到对应的 div 来“修复”这个问题。但我想加载数据并在不重新加载的情况下显示它。我什至不知道我是否在为此制作表格的正确轨道上,因此将不胜感激。谢谢!


解决方案(感谢@Jérémie RPK):

使按钮调用 JavaScript 函数:

<button onclick="loadGameData('{{game.game_id}}')">Show game summary</button>

使用style="display: none" 创建表以默认隐藏它。并制作一个空表,但使用您的偏好 id 和 。就我而言:

  <table style="display: none" id="game-{{game.game_id}}" class="table table-bordered">
    <thead id='game-{{game.game_id}}-thead-general'>
    </thead>
    <tbody id='game-{{game.game_id}}-tbody-general'>
    </tbody>
    <thead id='game-{{game.game_id}}-thead-blue'>
    </thead>
    <tbody id='game-{{game.game_id}}-tbody-blue'>
    </tbody>
    <thead id='game-{{game.game_id}}-thead-red'>
    </thead>
    <tbody id='game-{{game.game_id}}-tbody-red'>
    </tbody>
  </table>

使用此 javascript 代码创建表并调用新视图:

<script type="text/javascript">
  function loadGameData(gameId) {
      $.ajax({
          url : gameId, // the endpoint
          method: "GET",
          error: function(xhr, status, error) {
            alert("Server error");
        },
          success: function(gameJson){

              $('#game-'+ gameId + '-thead-general').append('<tr><th> GameId </th>'
                                                            + '<th> Server </th>'
                                                            + '<th> When </th>'
                                                            + '<th> Duration </th>'
                                                            + '<th> GameMode </th>'
                                                            + '<th> Patch </th></tr>')

              $('#game-'+ gameId + '-tbody-general').append('<tr><td>' + gameJson.gameId + '</td>'
                                                              + '<td>' + gameJson.platformId + '</td>'
                                                              + '<td>' + gameJson.gameCreation + '</td>'
                                                              + '<td>' + gameJson.gameDuration + '</td>'
                                                              + '<td>' + gameJson.gameMode + '</td>'
                                                              + '<td>' + gameJson.gameVersion + '</td></tr>')
                                                              
              $('#game-'+ gameId + '-thead-blue').append('<tr><th>' + gameJson.teams[0].win + ' (Blue Team) </th>'
                                                          + '<th> Rank </th>'
                                                          + '<th> KDA </th>'
                                                          + '<th> Damage </th>'
                                                          + '<th> CS </th>'
                                                          + '<th> Vision Score </th></tr>')
                                                          
              gameJson.participants.slice(0,5).forEach(participant => $('#game-'+ gameId + '-tbody-blue').append('<tr><td>' + participant.champion_name + ' ' + participant.summoner_name + '</td>'
                                                                                                              + '<td>' + participant.tier +  '</td>'
                                                                                                              + '<td>' +  participant.stats.kills + '/' +  participant.stats.deaths + '/' +  participant.stats.assists + '</td>'
                                                                                                              + '<td>' + participant.stats.totalDamageDealtToChampions + '</td>'
                                                                                                              + '<td>' + participant.stats.totalMinionsKilled + '</td>'
                                                                                                              + '<td>' + participant.stats.visionScore + '</td></tr>'))
              $('#game-'+ gameId + '-thead-red').append('<tr><th>' + gameJson.teams[1].win + ' (Blue Team) </th>'
                                                          + '<th> Rank </th>'
                                                          + '<th> KDA </th>'
                                                          + '<th> Damage </th>'
                                                          + '<th> CS </th>'
                                                          + '<th> Vision Score </th></tr>')
              gameJson.participants.slice(5,10).forEach(participant => $('#game-'+ gameId + '-tbody-red').append('<tr><td>' + participant.champion_name + ' ' + participant.summoner_name + '</td>'
                                                                                                              + '<td>' + participant.tier +  '</td>'
                                                                                                              + '<td>' +  participant.stats.kills + '/' +  participant.stats.deaths + '/' +  participant.stats.assists + '</td>'
                                                                                                              + '<td>' + participant.stats.totalDamageDealtToChampions + '</td>'
                                                                                                              + '<td>' + participant.stats.totalMinionsKilled + '</td>'
                                                                                                              + '<td>' + participant.stats.visionScore + '</td></tr>'))
              $('#game-'+gameId).show()
          }
      });
  }
</script>

将“url”更改为您想要的,并将新的 url 添加到您的 urls.py 以使该 URL 与您的 views.py 函数相匹配。像这样的:

path('path/URL/', views.getGameData, name="getGameData"),

getGameData 应该返回一个带有 return JsonResponse(JSON) 的 json 并记得添加 from django.http import JsonResponse

【问题讨论】:

    标签: python html django forms


    【解决方案1】:

    您必须使用 Ajax。 使用两个视图:主视图将发送数据以显示您的第一张图片。第二个将只发送您表所需的数据。 在您的模板中,当您点击“显示摘要”时,您将异步调用第二个视图,然后当接收到数据时,您将使用 JS 更新模板;我建议使用 Django 使用 JQuery。

    以单个数据为例:

    <div id="game-{{game.id}}">
        <button onclick="loadGameData({{game.id}})">Show game summary</button>
        <table style="display: none">
            <thead>
                <tr>
                    <th scope="col">Game Mode</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td class="game-mode"></td>
                </tr>
            </tbody>
        </table>
    </div>
    
    <script type="text/javascript">
        function loadGameData(gameId) {
            $.ajax({
                url: "{% url 'game-data' %}",
                method: "GET",
                error: function(xhr, status, error) {
                    alert("Server error");
                },
                success: function(gameData){
                    gameData.games.forEach(game => {
                        $('#game-'+gameId+' tbody').append('<tr><td>'+game.gameMode'+</td></tr>')
                    )}
                    $('#game-'+gameId).show()
                }
            });
        }
    </script>
    

    在你的新观点中:

    def getGameData(request):
        return JsonResponse({
            'gameMode': 'battle'
        })
    

    【讨论】:

    • 感谢您的回答,但我在$('game-'+gameId+' .game-mode).html(gameData.gameMode)Unterminated string literal.$('game-'+gameId').show()',' expected 上遇到了一些错误。另外,即使没有单击按钮,表格也会被加载,所以我应该在它之前添加一个 if 语句吗?谢谢
    • 对不起,它是:$('#game-'+gameId+' .game-mode').html(gameData.gameMode)$('#game-'+gameId).show()。对于默认显示的表格,添加 CSS display: none
    • 谢谢,现在按预期工作。但是,我真的不知道如何在我的模板中正确操作 json。我正在返回一个看起来像 this 的 json,之前在我的模板中我有 this。基本上,我用{% for player in game_data.participants|slice:":5" %} 遍历了参与者。我访问 json.participants 并将其切成两半以将它们分成两个团队。我应该如何循环这个 json 并使用 AJAX 切片?
    • data.teams.forEach(team =&gt; $('#tbodyId').append('&lt;tr&gt;&lt;td&gt;team.score&lt;/td&gt;&lt;/tr&gt;'))这样使用JS
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多