0

Okay guys, I'm pretty stumped with this one!

So, I am trying to routinely post the contents of a txt file onto a website. (IE update the file daily and post the new one)

I am using django as the framework and have everything working..... almost. Following this question: Periodically fetch data and display it with Django

I set up the views, templates, and urls so that $.ajax is called whenever I load the page. And that part works! If I manually load the page into a browser, the data is updated and displayed correctly. However, automating it has been problematic.

If I had to guess, I would say that.. for some reason, $.ajax is not being called when there is not a browser.

Here is the requests.py code:

import requests
login_url = "http://127.0.0.1:8000/login/"
soup_url = "http://127.0.0.1:8000/soups/pull/"
test_url = "http://127.0.0.1:8000/profiles/myusername"
UN = 'myusername'
PW = 'mypassword'

with requests.session() as client:
    # get the login page
    client.get(login_url)

    # save session credentials
    csrftoken = client.cookies['csrftoken']
    login_data = {'username':UN,'password':PW,'csrfmiddlewaretoken': csrftoken}


    # login
    client.post(login_url, data=login_data)
    client.get(test_url)

    # get the page that loads $.ajax
    client.get(soup_url)

And, the $.ajax request comes from:

{% extends "base.html" %}


{% block script %}
<script>

$(document).ready(function(){
  function pullSoup(){
      var token = "{{ csrf_token }}"
      var soup_text = "{{ soup_text }}"
      var soup_text = soup_text.replace(/&amp;/gi, "&").replace(/&quot;/gi, "\"").replace(/&apos;/gi, "'").replace(/&gt;/gi, ">").replace(/&lt;/gi, "<");
      var formdata = "csrfmiddlewaretoken=" + token + "&content=" + soup_text


      $.ajax({
                  url: "/api/chirp/create/",
                  data: formdata,
                  method: "POST",

                  success: function(data){
                      console.log(data)
                      console.log(formdata)
                      attachChirp(data, true)
                  },

                  error: function(data){
                      console.log("error")
                      console.log(data.statusText)
                      console.log(data.status)
                  }
      })

  }

  pullSoup()



});
</script>
{% endblock script %}



{% block content %}
<p>you just pulled soup. unless you know what you're doing... you probably
    should not do that again.</p>
{% endblock content %}

I tried pulling the ajax request out of $(document).ready just in case that was the issue... but got the same results. When I manually load the page, the server outputs something like this:

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[28/Mar/2018 01:39:33] "GET /soups/pull/ HTTP/1.1" 200 6478
[28/Mar/2018 01:39:35] "POST /api/chirp/create/ HTTP/1.1" 201 739

And when I run the requests.py file it outputs:

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[28/Mar/2018 01:41:01] "GET /login/ HTTP/1.1" 200 4887
[28/Mar/2018 01:41:02] "POST /login/ HTTP/1.1" 302 0
[28/Mar/2018 01:41:02] "GET / HTTP/1.1" 200 13006
[28/Mar/2018 01:41:02] "GET /soups/pull/ HTTP/1.1" 200 6478

So, it has an exit code of 200 and seems like it's happy... except that the post never actually goes through! I would really appreciate any thoughts / suggestions. I'm pretty out of ideas right now. Thanks!

spinach
  • 89
  • 1
  • 5
  • Hey it seem its doing what it is meant to do. Its posting data when you load the page. Is your question "How to make this ajax call run periodically ?" – Amar Mar 28 '18 at 07:54
  • That is probably a better way to ask it! I figured that requesting the page would get it to run (because it's easy to set up a cron-job that will request the page), but it doesn't seem like it works that way. – spinach Mar 28 '18 at 07:55
  • Also, I should clarify that I want this to happen in the background-- it seems like setInterval and setTimeout both require someone to actively be on the page! – spinach Mar 28 '18 at 08:02
  • then this is actually not a django question. You should tag frontend tech – Amar Mar 28 '18 at 08:04
  • done, although I don't actually want the process to require a user at all. Do you know if django has an equivalent of an ajax post? It's a daily update – spinach Mar 28 '18 at 08:10
  • This question is very bizarre. What are you expecting to run the Ajax here? Yes, of course it doesn't run if there's no browser, because JS is a thing that runs in the browser. Why are you using Ajax at all, rather than getting your requests script to do the POST? – Daniel Roseman Mar 28 '18 at 08:43
  • So I started out using requests.post( ) with the credentials and a json of the content, but I kept getting a 403 forbidden error. I tried everything I could think of from passing csrf tokens to using the @csrf_exempt on the methods called and nothing worked. I'm thinking that I might need to change the whole site to use token authentication.. but in the mean-time it seemed worth trying a different approach to make the posts. I would love any direction you can give, I'm quite new to web frameworks! – spinach Mar 28 '18 at 13:51
  • It seemed like calling POST was causing the csrf_token to change for some reason. Also, by "changing the site to use token authentication" I mean jwt token authentication. – spinach Mar 28 '18 at 13:58
  • Figured it out! The login post was resetting the csrftoken and I was not updating it. Also, I had to set referer=url. I'll write it up later if I have time – spinach Mar 28 '18 at 14:46

0 Answers0