0

Where can i put ajax get data code in Wagtail? I have following page model:

class ScreencastPage(Page):
    content_panels = Page.content_panels + [
        InlinePanel(
            'groupstage_screencast_relationship', label="Choose Teams",
            panels=None, max_num=2),
    ]

    parent_page_types = ['home.HomePage']

    def matches(self):
        matches = [
            n.match for n in self.groupstage_screencast_relationship.all()
        ]

        return matches

And my template:

  {% for spiel in page.matches %}
    {% if forloop.first == forloop.last %}
    <div id="fullscreen">
      <ul class="ulup">
        <li class="logo_bg first_team">{% image spiel.team_1.team_logo width-400 class="logo" %}<p>{{spiel.team_1.title}}</p></li>
        <li class="first_team_score">{{ spiel.team_1_total_score }}</li>
        <li class="colons">:</li>
        <li class="second_team_score">{{ spiel.team_2_total_score }}</li>
        <li class="logo_bg second_team">{% image spiel.team_2.team_logo width-400 class="logo" %}<p>{{spiel.team_2.title}}</p></li>
      </ul>
    </div>
    {% endif %}
  {% endfor %}

I started writing js. Just exaple:

$(document).ready(function() {
  setInterval(function(){
    $.ajax({
      type: "GET",
      url: {% pageurl page %},
      data: {},
      success: function(data) {
        console.log(data);
        $(".first_team_score").contents()[0].textContent = data.team_1_total_score;
        $(".second_team_score").contents()[0].textContent = data.team_2_total_score;
      }
    })
  }, 10000);
});

The idea is that the page will automatically update the value of <li class="first_team_score">{{ spiel.team_1_total_score }}</li> and <li class="second_team_score">{{ spiel.team_2_total_score }}</li> without reloading the page.

I found here great example, but they using view.py

We also need to write a new view.py or have wagtail some method for that?

UPDATE

Thanks @Ben-Dickinson from wagtail slack community. He shared a link to the documentation where it is indicated how it's possible to solve such a problem.

I have here another problem. How to convert matches to json?

khashashin
  • 1,058
  • 14
  • 40

1 Answers1

1

To catch ajax requests we can use the Page serve() method and use if request.is_ajax():. So I did following inside my ScreencastPage(Page):

def serve(self, request):
    if request.is_ajax():
        result = [
            {
                'team_1_name': match.team_1.title,
                'team_1_score': match.team_1_total_score,
                'team_2_name': match.team_2.title,
                'team_2_score': match.team_2_total_score,
            }
            for match in self.matches()
        ]
        json_output = json.dumps(result)
        return HttpResponse(json_output)
    else:
        return super(ScreencastPage, self).serve(request)

This code from above was the result of help from @gasman, this topic you can find here Converting value to json inside serve method

The final result of the HTML/JS code is:

<div id="match1">
  <ul class="ulup">
    <li class="logo_bg first_team">{% image spiel.team_1.team_logo width-400 class="logo" %}<p>{{spiel.team_1.title}}</p></li>
    <li class="first_team_score">{{ spiel.team_1_total_score }}</li>
    <li class="colons">:</li>
    <li class="second_team_score">{{ spiel.team_2_total_score }}</li>
    <li class="logo_bg second_team">{% image spiel.team_2.team_logo width-400 class="logo" %}<p>{{spiel.team_2.title}}</p></li>
  </ul>
</div>

JS:

$(document).ready(function() {
  setInterval(function(){
    $.ajax({
      type: "GET",
      url: {% pageurl page %},
      dataType: 'json',
      success: function(data) {
        $("#match1 .first_team").contents()[0].textContent = data[0]["team_1_name"];
        $(".first_team_score").contents()[0].textContent = data[0]["team_1_score"];
        $("#match1 .second_team").contents()[0].textContent = data[0]["team_2_name"];
        $(".second_team_score").contents()[0].textContent = data[0]["team_2_score"];
      }
    })
  }, 10000);
});

data[0] is becoz my data returns database of two matches and i need only first one

enter image description here

khashashin
  • 1,058
  • 14
  • 40