Получение данных формы в питон и фласк (ajax?)

amv

Новичок
Пользователь
Июн 23, 2020
19
2
3
Доброго времени суток!
Есть тренировочное веб-приложение на питоне. Приложение получает список топ-новостей с западного сервиса и генерит блоки анонса этих новостей на HTML странице. В черновике один блок топ-новости сейчас выглядит примерно так:

HTML:
<article class="topnewsitem">
   <hr>
  <h6><span>1. Trump administration asks Supreme Court to strike down Obamacare - The Washington Post.</span></h6>
    <span>Дата публикации: </span>2020-06-26T08:06:32Z<br>
   <img class='topnewsimage' src='https://www.washingtonpost.com/wp-apps/imrs.php?src=https://arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/55NIUCFWLUI6VGQ52PNRZPQHZY.jpg&amp;w=1440' alt=''>
  <span>Автор: </span>Tim Elfrink, Meagan Flynn<br>
  <span>Краткое описание: </span>House Speaker Nancy Pelosi (D-Calif.) denounced the move as “an act of unfathomable cruelty” during the pandemic.<br>
  <span>Ссылка на статью: </span><a href='https://www.washingtonpost.com/nation/2020/06/26/trump-obamacare-supreme-court-brief/' target="_blank">Trump administration asks Supreme Court to strike down Obamacare - The Washington Post</a><br>
  <span>Содержание: </span>House Speaker Nancy Pelosi (D-Calif.) responded to the brief by saying there is no moral excuse for the Trump Administrations disastrous efforts to take away Americans health care.&#34; Dismantling the A… [+5306 chars]<br>
  <span></span><br>
</article>

Теперь предполагается, что юзер, просматривая список анонсов топ-новостей, может удалить со страницы (и из базы) те новости, которые ему не интересны.

Подскажите, какой инструмент (питоновский, не питоновский) для этого нужен и как это делается, в общих чертах, у меня просто пока нет понимания по таким задачам..
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Подскажите, как в данном случае правильно вытащить json данные, полученные из формы, ведь они уже здесь!
Вытащить данные, которые вы отправляйте можно с помощью декодирования байт:
Python:
@app.route("/getandpost", methods=["GET", "POST"])
def getandpost():
    print(request.method)  # получаем ессно, POST
    if request.method == "POST":
        print(request.is_json)  # Пишет True - типа полученный ответ и есть Джейсон???
        print(request.mimetype)  # application/json -
        print(request.data)  # вот они бинарные данные, например
        res = request.data.decode('utf-8')
        print(res) # тут строка имя=значение&имя2=значение2&...
Проблема в том, что эти данные не являются JSON`ом. Правильный JSON это {"name":"value", "name2":"value2"}.
Вот пример отправки и приема JSON.
Шаблон:
HTML:
<!DOCTYPE html>
<html>
<head>
  <title>test</title>
  <meta charset="utf-8">
</head>
<body>
  <form id = "changeform" action="/getandpost" method="post" name = "changeform">
    <input type="text" id="test1" name="test1" />
    <input type="text" id="test2" name="test2" />
    <input type="text" id="test3" name="test3" />
      <button type="button" id='submit' class="btn btn-primary" name = "submitbutton">Сохранить изменения</button>
    </form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>   
    <script>
    document.addEventListener('DOMContentLoaded', function(){
      document.getElementById('submit').addEventListener('click', do_request);
    });

    function do_request() {
      axios.post('http://127.0.0.1:5000/getandpost', {
        test1: document.querySelector('#test1').value,
        test2: document.querySelector('#test2').value,
        test3: document.querySelector('#test3').value
      })
      .catch(err => console.error(err));
    }
    </script>
</body>
</html>
Роут:
Python:
@app.route("/getandpost", methods=["GET", "POST"])
def getandpost():
    print(request.method)  # получаем ессно, POST
    if request.method == "POST":
        print(request.is_json)  # Пишет True - типа полученный ответ и есть Джейсон???
        print(request.mimetype)  # application/json -
        print(request.data)  # вот они бинарные данные, например
        res = request.get_json()
        print(res)
        print(res['test1'])
        print(res['test2'])
        print(res['test3'])
 
  • Мне нравится
Реакции: Student

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
Это делается на Javascript и AJAX запрос на backend с ID новости которую нужно удалить. Питон тут совсем не имеет отношения, разве, что принимает запрос по определенному адресу /remove?id=99.

Динамическое удаление элементов из страницы для индивидуального пользователя выполняется через Javascript. Оно может удаляться физически или добавить CSS класс .hide { display: none }
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Подскажите, какой инструмент (питоновский, не питоновский) для этого нужен и как это делается, в общих чертах, у меня просто пока нет понимания по таким задачам..
Нужно реализовать простой CRUD (Create, Retrieve, Update, Delete), а точнее метод Delete.
У вас реализован только парсинг данных из внешнего источника в базу данных и их вывод на клиент (Retrieve).
Нужно на сервере сделать метод (url и view, template если на django или route, если на flask) для удаления статьи из базы. А на клиенте (в шаблоне) сделать кнопку (или ссылку), которая делает AJAX-запрос на сервер и удаляет нужную статью.
Вот тут можно почитать про CRUD на flask: ссылка.
Вот тут пример для django: ссылка.
Также можете просто погуглить про реализацию CRUD на flask/django.
 

amv

Новичок
Пользователь
Июн 23, 2020
19
2
3
Видимо, я где-то путаю белое с горячим. Питон + Фласк
Есть форма, пользователь должен поменять в ней некие данные и по нажатию кнопки записать в базу
Сейчас код примерно такой:
HTML:
<form id = "changeform" action="/getandpost" method="post" name = "changeform">
... тут всякие инпуты
  <button type="submit" class="btn btn-primary" name = "submitbutton">Сохранить изменения</button>
    </form>

Затем я пытаюсь отправить измененные данные для записи на сервер

JavaScript:
<script>
    $("#changeform").on("submit", function(){
      $.ajax({
        url: '/getandpost',
        method: 'post',
        dataType: 'json',
        contentType: 'application/json',
        data: $("#changeform").serialize(),
        success: function(data){
          $('#message').html(data);
        }
      });
    });
    </script>


Пытаюсь эти данные там принять

Python:
@app.route("/getandpost", methods=["GET", "POST"])
@login_required
def getandpost():
    if request.method == "POST":
        print('Получен ajax от формы name = #changeform') - отрабатывает
        print (request.is_json) # False - json не получен???
        print(request.form.get("usersecondname")) # отрабатывает, возвращает value соответствующего инпута

    return "000"

Я предполагал, что при таком раскладе я выловлю json в def getandpost():, а как его разобрать и затолкать в базу данные из него я уже знаю.
Но print (request.is_json) возвращает False, то есть я не получил json? Почему? И как его в конце концов выловить? И вообще, был ли он отправлен?

print(request.form.get("usersecondname")) естественно, возвращает данные из инпута формы name = "usersecondname" как и положено. Я конечно умею таким образом получить значения всех инпутов формы и записать их в базу, но мне интересно было попробовать именно ajax в целях самосовершенствования.

Запустил в консоли Firefox'a $("#changeform").serialize(), форма id = "changeform" нормально сериализовалась. Покурил источники на русском и английском. Читал орфографический словарь. Много думал. Видимо, не хватает базовых знаний.

Подскажите, что не так с ajaх'ом? Где я иду неверным путем?
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Подскажите, что не так с ajaх'ом? Где я иду неверным путем?
По коду и вашим комментариям видно что форма у вас отрабатывает нормально и передает post-запрос на сервер по нажатию на кнопку с типом submit. Это поведение форму по умолчанию.
Чтобы работал ajax нужно или отменить поведение по умолчанию, то есть добавить в скрипт preventDefault():
JavaScript:
<script>
    $("#changeform").on("submit", function(event){
      event.preventDefault();
      $.ajax({
        url: '/getandpost',
        method: 'post',
        dataType: 'json',
        contentType: 'application/json',
        data: $("#changeform").serialize(),
        success: function(data){
          $('#message').html(data);
        }
      });
    });
    </script>
Или изменить тип у кнопки чтобы она просто не отправляла форму, а ajax-запрос отправлять по клику на нее:
HTML:
<button type="button" class="btn btn-primary" name = "submitbutton">Сохранить изменения</button>
JavaScript:
<script>
    $("#changeform").on("click", function(){
      $.ajax({
        url: '/getandpost',
        method: 'post',
        dataType: 'json',
        contentType: 'application/json',
        data: $("#changeform").serialize(),
        success: function(data){
          $('#message').html(data);
        }
      });
    });
    </script>
Также может возникнуть проблема с CORS. Вот тут можете почитать как ее решить: ссылка.
 

amv

Новичок
Пользователь
Июн 23, 2020
19
2
3
Спасибо за дельную подсказку.
Теперь новая беда. Питон + Фласк
Отправил данные формы
JavaScript:
<script>
      $("#changeform").on("submit", function(event){
        event.preventDefault();
        $.ajax({
          url: '/getandpost',
          method: 'post',
          dataType: 'json',
          contentType: 'application/json',
          data: $("#changeform").serialize(),
          success: function(data){
            $('#message').html(data);
          }
        });
      });
      </script>

Получил данные в питоне

Python:
@app.route("/getandpost", methods=["GET", "POST"])
@login_required
def getandpost():
    print(request.method)# получаем ессно, POST
    if request.method == "POST":
        print (request.is_json) # Пишет True - типа полученный ответ и есть Джейсон???
        print(request.mimetype) # application/json -
        print(request.data)# вот они бинарные данные, например
        #b'usersurname=%D0%9F%D1%83%D0%BF%D0%BA%D0%B8%D0%BD&userfirstname=%D0%98%D0%B3%D0%BD%D0%B0%D1%82&usersecondname=%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2%D0%B8%D1%87&myemail=Some%20email'

Вот же они, данные, родные, получены.
Теперь не могу допетрить как дотянуться до джейсона.
Уж что я только не делал от отчаяния, например,

Python:
#json_data = request.get_json(force=True)
#json_data = request.json()
#json_data = request.json
# ну и прочий треш и угар, который мне даже стыдно показывать.

А заканчиваюся мои попытки вот чем:
127.0.0.1 - - [09/Jul/2020 14:11:46] "POST /getandpost HTTP/1.1" 400 -
и все.

Подскажите, как в данном случае правильно вытащить json данные, полученные из формы, ведь они уже здесь!
Разбирать полученный json я уже пробовал с помощью модуля json и у меня все получалось.
Но сейчас пока мне и разбирать нечего.
 

amv

Новичок
Пользователь
Июн 23, 2020
19
2
3
Спасибо, добрый человек :)) Мною пятно темное пройдено, дальше кодить отправляюсь я
 
  • Мне нравится
Реакции: Student

Форум IT Специалистов