Форум программистов, компьютерный форум, киберфорум
Наши страницы
Python: Django
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
m0nte-cr1st0
791 / 432 / 185
Регистрация: 15.01.2019
Сообщений: 1,665
Записей в блоге: 1
1

Сохранение формы с изображениями без перезагрузки страницы, ajax

27.03.2019, 03:14. Просмотров 1480. Ответов 8
Метки нет (Все метки)

Python
1
2
3
4
5
6
7
8
9
10
class IdentificationForm(forms.ModelForm):
    class Meta:
        model = RequestUser
        fields = ('main_photo', 'profile_photo', )
 
    def clean_image(self):
        ....
 
    def clean_image2(self):
        ....
HTML5
1
2
3
4
5
6
<form action="" class="edit_form new_event" enctype="multipart/form-data" method="POST">
  {% csrf_token %}
  {{ form.main_photo }}
  {{ form.profile_photo }}
  <button class="submit mgln" type='button'>Послать запрос</button>
</form>
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def identification_view(request):
    if request.method == 'POST':
        form = IdentificationForm(request.POST, request.FILES)
        if form.is_valid():
            print('ok')
            req_user = form.save(commit=False)
            req_user.user = request.user
            req_user.save()
            return HttpResponse('image upload success')
    else:
        form = IdentificationForm()
    identifications  = RequestUser.objects.filter(user = request.user)
 
    return render(request, 'accounts/identification.html', {'form': form, 'identifications': identifications})
Всё работает, но вот после создания объекта происходит редирект. Это как-то не очень красиво смотрится.
Нужно, чтобы после создания объекта высвечивалось хоть какое-то уведомление, что объект создан, пусть даже простой алерт.

Вот, как я пробовал сделать.
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
$('.mgln').on('click', function(){
  main_photo = $('input[name=main_photo]').val();
  profile_photo = $('input[name=profile_photo]').val();
//  console.log(main_photo)
  
  data = {
              main_photo: main_photo,
              profile_photo: profile_photo,
              csrfmiddlewaretoken: '{{ csrf_token }}'
            }
 
  console.log(data)
  $.ajax({
    type: "POST",
    url: "{% url 'identification_view' %}",
    data: data,
    cache: false,
    processData: false,
    contentType: false,
    success: function(result) {
      alert('Ожидайте. Ваши документы приняты в обработку.');
    },
    error: function(result) {
      alert('Произошла ошибка. Попробуйте позже.');
    }
  })
})
</script>
Вылетает с 403 ошибкой - csrf token. Пытался нагуглить - нашёл различные решения, не помогло. Можно, в принципе, на GET запрос переделать... Но не хотелось бы. Может, кто сталкивался с таким?

Добавлено через 3 минуты
Отрисовывается следующий шаблон.
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<form action="" class="edit_form new_event" enctype="multipart/form-data" method="POST">
          <input type="hidden" name="csrfmiddlewaretoken" value="i1zMpWDhHR5MSXALBi4WA8nNZIuQIlX1236DgnVQHAByJfIHcVsI1nSRuXRgu1AX9oo">
            <div class="field inline">
                <div class="subhead">Фото главной страницы паспорта:</div>
                <input type="file" name="main_photo" required="" id="id_main_photo">
                <label for="foto1" class="id_foto">
                    <div class="addPhoto">
                        <div class="button"></div>
                    </div>
                </label>
            </div>
            <div class="field inline">
                <div class="subhead">Фото в профиль с раскрытым паспортом в руке:</div>
                <input type="file" name="profile_photo" required="" id="id_profile_photo">
                <label for="foto2" class="id_foto">
                    <div class="addPhoto">
                        <div class="button"></div>
                    </div>
                </label>
            </div>
            <div class="center">
              <button class="submit mgln" type="button">Послать запрос</button>
            </div>
        </form>
Также возникает проблема с тем, что появляется какой-то фейк путь файла... Тоже искал в интернете, подобных проблем много. Не удалось решить(

Вроде бы, эти 2 проблемы распространённые, и решения есть, но что-то мне никак не удаётся(

Добавлено через 31 минуту
Попытка решить через GET убрала проблему с токеном. Хотя всё же правильней было бы через POST, наверное.

Python
1
2
3
4
5
6
7
8
9
10
def identification_view(request):
    if request.method == 'GET':
        form = IdentificationForm()
        if request.is_ajax():
            main_photo = request.GET.get('main_photo')             #C:\fakepath\<имя_файла1>
            print(main_photo)
            profile_photo = request.GET.get('profile_photo')         #C:\fakepath\<имя_файла2>
            print(profile_photo)
 
    return render(request, 'accounts/identification.html', {'form': form})
Нужно как-то устранить проблему с fakepath(
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.03.2019, 03:14
Ответы с готовыми решениями:

Отправка формы без перезагрузки страницы (AJAX)
Все работает нормально, но почему то дублируются поля ввода ИМЯ и СООБЩЕНИЕ после нажатия на кнопку...

Отправка формы без перезагрузки страницы Ajax
Здравствуйте! Никак не могу отправить. В чем ошибка, если есть? Файлы index.html и jquery.js...

Ajax отправление данных из формы без перезагрузки страницы (почему-то перезагружается)
Доброго всем дня. реализую вот такой вот простой механизм: function tsend(){ $.ajax({ ...

Пример простейшего калькулятора на PHP без перезагрузки страницы (чистый Ajax, без jQuery и других библиотек)
Привет. Это, в каком-то смысле, продолжение креатива...

ajax загрузка страницы без перезагрузки
ajax загрузка страницы без перезагрузки внутри контента Пример у меня есть ссылка...

8
netBool
317 / 298 / 171
Регистрация: 16.11.2010
Сообщений: 1,067
Записей в блоге: 9
Завершенные тесты: 5
28.03.2019, 10:41 2
Лучший ответ Сообщение было отмечено m0nte-cr1st0 как решение

Решение

Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
Хотя всё же правильней было бы через POST, наверное
А в csrfmiddlewaretoken: '{{ csrf_token }}' верный csrf_token записывается? Не уловил, откуда вы его берете...

Я обычно делаю, как в документации рекомендуется получать csrf на js из куки (пример с оф док):

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
    var csrftoken = getCookie('csrftoken');
}
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
Также возникает проблема с тем, что появляется какой-то фейк путь файла...
Это проблема не в джанго. На со есть решение, в таком виде:

Javascript
1
2
3
4
5
6
7
8
9
var fd = new FormData($('#fbndoc').get(0));
fd.append("CustomField", "This is some extra data");//add all you data here like this
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // tell jQuery not to process the data
  contentType: false   // tell jQuery not to set contentType
});
Если в кратце, то рекомендуется использовать FormData для передачи изображений через AJAX
1
m0nte-cr1st0
791 / 432 / 185
Регистрация: 15.01.2019
Сообщений: 1,665
Записей в блоге: 1
28.03.2019, 12:48  [ТС] 3
netBool, спасибо, пробовал и через FormData
решил пока через GET делать, чтобы с токеном этим не возиться ещё. Потом на POST буду переделывать.
Вот, что получается
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
  $('.mgln').on('click', function(){
    var form = $('form').get(0);
    var main_photo = new FormData(form);
    main_photo.append('file1', $('input[name=main_photo]'))
    console.log(main_photo)
  data = {
      main_photo: main_photo,
    }
 
    console.log(data)
    $.ajax({
      type: "GET",
      url: "{% url 'identification_view' %}",
      data: data,
      cache: false,
      processData: false,
      contentType: false,
      success: function(result) {
        alert('Ожидайте. Ваши документы приняты в обработку.');
      },
      error: function(result) {
        alert('Произошла ошибка. Попробуйте позже.');
      }
    })
  })
</script>
Аякс успешно уходит и приходит. В консоле выводится пустая, вроде бы FormData, с наборами свойств.
Сохранение формы с изображениями без перезагрузки страницы, ajax


Но во views прилетает None, по сути.
Вот, что выдают запросы FILES и GET соответственно
Код
<MultiValueDict: {}>
<QueryDict: {u'[object Object]': [u''], u'_': [u'1553766039811']}>
0
netBool
317 / 298 / 171
Регистрация: 16.11.2010
Сообщений: 1,067
Записей в блоге: 9
Завершенные тесты: 5
28.03.2019, 13:10 4
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
netBool, спасибо, пробовал и через FormData
решил пока через GET делать, чтобы с токеном этим не возиться ещё. Потом на POST буду переделывать.
Забыл добавить: FormData создана для работы через POST.

Да и стандарт вряд ли предусматривает передачу файлов в get-запросах
1
m0nte-cr1st0
791 / 432 / 185
Регистрация: 15.01.2019
Сообщений: 1,665
Записей в блоге: 1
28.03.2019, 13:27  [ТС] 5
netBool, позже попробую, отпишу
0
m0nte-cr1st0
791 / 432 / 185
Регистрация: 15.01.2019
Сообщений: 1,665
Записей в блоге: 1
31.03.2019, 19:36  [ТС] 6
Цитата Сообщение от netBool Посмотреть сообщение
А в csrfmiddlewaretoken: '{{ csrf_token }}' верный csrf_token записывается?
как понять, верный ли csrf_token?
Если смотреть в форме хтмл {{csrf_token}} - там один, в js (по этой функции) - другой.
Пробую через POST. Как в доках делаю, вроде, но не получается(
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
0
netBool
317 / 298 / 171
Регистрация: 16.11.2010
Сообщений: 1,067
Записей в блоге: 9
Завершенные тесты: 5
31.03.2019, 21:39 7
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
Если смотреть в форме хтмл {{csrf_token}} - там один, в js (по этой функции) - другой.
Да, он и не должен совпадать, хотя в документации не указано это явно. Но:
The CSRF token is also present in the DOM, but only if explicitly included using csrf_token in a template. The cookie contains the canonical token; the CsrfViewMiddleware will prefer the cookie to the token in the DOM. Regardless, you’re guaranteed to have the cookie if the token is present in the DOM, so you should use the cookie!
- косвенно указывает на то, что они могут быть разными. И исходя из этой цитаты, CSRF, взятый из куки, предпочтительней / имеет больший приоритет / нежели взятый из DOM.

Что касается моего опыта, то для ajax всегда беру его из cookie.

Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
как понять, верный ли csrf_token?
Если csrf_token будет неверный, то сервер выдаст ошибку - что-то типа CSRF token missing or incorrect.
1
m0nte-cr1st0
791 / 432 / 185
Регистрация: 15.01.2019
Сообщений: 1,665
Записей в блоге: 1
01.04.2019, 12:30  [ТС] 8
Вот как получилось, кстати. Без функции получения токена, кстати.
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var token = '{{csrf_token}}';
$('.mgln').on('click', function(){
    formData = new FormData();
    formData.append('file1', $('input[name=main_photo]')[0].files[0])
    formData.append('file2', $('input[name=profile_photo]')[0].files[0])
    $.ajax({
      headers: { "X-CSRFToken": token },
      type: "POST",
      url: "{% url 'identification_view' %}",
      data: formData,
      processData: false,
      contentType: false,
      success: function(result) {
        alert('Ожидайте. Ваши документы приняты в обработку.');
      },
      error: function(result) {
        alert('Произошла ошибка. Попробуйте позже.');
      }
    })
  })
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def identification_view(request):
    if request.method == 'POST':
        form = IdentificationForm(request.POST, request.FILES)
        if request.is_ajax():
            print(dir(request.FILES))
            main_photo = request.FILES.get('file1')
            profile_photo = request.FILES.get('file2')
            RequestUser.objects.create(
            user = request.user,
            main_photo = main_photo,
            profile_photo = profile_photo
            )
            return HttpResponse('image upload success')
    else:
        form = IdentificationForm()
    identifications  = RequestUser.objects.filter(user = request.user)
 
    return render(request, 'accounts/identification.html', {'form': form, 'identifications': identifications})
1
netBool
317 / 298 / 171
Регистрация: 16.11.2010
Сообщений: 1,067
Записей в блоге: 9
Завершенные тесты: 5
04.04.2019, 09:23 9
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
Вот как получилось, кстати. Без функции получения токена, кстати.
Неплохо получилось
0
04.04.2019, 09:23
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2019, 09:23

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Ajax + js загрузка контента без перезагрузки страницы
&lt;script&gt; function showContent(link) { var cont =...

AJAX или JS ReCaptcha 2.0 без перезагрузки страницы
Доброго времени суток! Что-то как ни крути у меня не получается навесить капчу от гугл 2.0. Мне...

Ajax обновление контента без перезагрузки страницы
Ребята доброго времени! Помогите пожалуйста! Есть не доработанный сайт, в нем есть страница, в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.