Форум программистов, компьютерный форум, киберфорум
Python: Django
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
959 / 516 / 221
Регистрация: 15.01.2019
Сообщений: 1,979
Записей в блоге: 1
1

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

27.03.2019, 03:14. Просмотров 1808. Ответов 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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.03.2019, 03:14
Ответы с готовыми решениями:

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

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

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

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

8
319 / 300 / 171
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
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
959 / 516 / 221
Регистрация: 15.01.2019
Сообщений: 1,979
Записей в блоге: 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
319 / 300 / 171
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
28.03.2019, 13:10 4
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
netBool, спасибо, пробовал и через FormData
решил пока через GET делать, чтобы с токеном этим не возиться ещё. Потом на POST буду переделывать.
Забыл добавить: FormData создана для работы через POST.

Да и стандарт вряд ли предусматривает передачу файлов в get-запросах
1
959 / 516 / 221
Регистрация: 15.01.2019
Сообщений: 1,979
Записей в блоге: 1
28.03.2019, 13:27  [ТС] 5
netBool, позже попробую, отпишу
0
959 / 516 / 221
Регистрация: 15.01.2019
Сообщений: 1,979
Записей в блоге: 1
31.03.2019, 19:36  [ТС] 6
Цитата Сообщение от netBool Посмотреть сообщение
А в csrfmiddlewaretoken: '{{ csrf_token }}' верный csrf_token записывается?
как понять, верный ли csrf_token?
Если смотреть в форме хтмл {{csrf_token}} - там один, в js (по этой функции) - другой.
Пробую через POST. Как в доках делаю, вроде, но не получается(
https://developer.mozilla.org/... ata/append
0
319 / 300 / 171
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
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
959 / 516 / 221
Регистрация: 15.01.2019
Сообщений: 1,979
Записей в блоге: 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
319 / 300 / 171
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
04.04.2019, 09:23 9
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
Вот как получилось, кстати. Без функции получения токена, кстати.
Неплохо получилось
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.04.2019, 09:23

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

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

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.