Django에서 Ajax (일반 클래스 뷰 사용)

「Django Ajax」로 검색하면 몇개의 기사가 히트하지만 대부분이 함수 베이스 뷰에 의한 것이었으므로, 범용 뷰를 사용한 코드를 해설.

범용 뷰 잘 모르는 분은 우선 그곳에 입문합시다.
  • Django의 클래스 기반 일반 뷰 시작 및 사용법 샘플
  • Django의 범용 클래스 뷰를 정리하여 구현에 대해 언급

  • 이것은 나의 견해이지만 Django를 채택하는 큰 장점 중 하나가 클래스 기반 인 범용 뷰를 활용하는 것이라고 생각합니다.
    어쩌면 이것이 모범 사례라고 생각합니다.

    완제품 이미지



    GitHub - skokado/django_ajax: Django + Ajax 샘플

    입력한 문자열을 화면에 표시한다는 것.

    간단하게 사양을 정해 둔다.
  • 사용자는 /greet에 브라우저로 액세스
  • 양식에 입력 한 값 (name)은 POST 메서드로 보냅니다.
  • ※POST 메소드의 송신처 패스는 화면의 표시와 같다 /greet

  • views.py는 Ajax 요청 (XMLHttpRequest)을 식별하고 다른 처리와 분리합니다
  • Ajax 요청에 대해 こんにちは、[name]さん!라는 메시지를 <p> 태그로 화면에 표시



  • 코드 해설



    구성 요소는 크게 아래.
  • urls.py : 라우팅 (URL 바이딩)
  • forms.py : 사용자가 데이터를 입력하기위한 양식 정의
  • views.py : 요청 처리를 기술.
  • 일반 뷰에서 FormView 사용
  • Request.is_ajax()를 사용하여 Ajax 요청 식별

  • 템플릿 (index.html) : 표시 할 HTML. 본 기사에서는 jQuery도 동봉한다.

  • 준비



    Django 프로젝트와 Django 어플리케이션의 작성을 적당하게 끝낸다.
    ※프로젝트명: django_ajax , 어플리케이션명: greeting로 한다.

    urls.py에 라우팅 규칙이 있습니다.



    urls. py



    사용할 경로는 /greet입니다.

    django_ajax/urls.py
    from django.urls import path
    
    from . import views
    
    
    urlpatterns = [
        path('greet/', views.GreetView.as_view(), name='greet'),
    ]
    

    양식. py


    name만 입력하세요.

    greeting/forms.py
    from django import forms
    
    
    class GreetForm(forms.Form):
        name = forms.CharField(label='あなたの名前は?')
    

    index.html


  • 폼 부분
  • <div id="result">의 요소 아래에 こんにちは、[name]さん!라는 문언이 추가되어 간다.
    (라고 하는 처리를 jQuery에 기술한다)
    <h1>Let's Greeting!</h1>
    <form action="" method="post">{% csrf_token %}
        {{ form }}
        <button type="submit">送信</button>
    </form>
    
    <div id="result">
        <!-- ここにあいさつ文の <p> タグ要素が追加されていく -->
    </div>
    
  • 스크립트 부분

  • jQuery 부분에 대해서도 상기의 사양대로 되어 있는 것이 왠지 읽을 수 있다고 생각한다.
    또한 (slim이 아닌) jQuery가 필요하기 때문에로드합니다.
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script>
    // 送信ボタンにイベントリスナーを設定。内部に Ajax 処理を記述
    $("form").submit(function(event) {
        event.preventDefault();
        var form = $(this);
        $.ajax({
          url: form.prop("action"),
          method: form.prop("method"),
          data: form.serialize(),
          timeout: 10000,
          dataType: "text",
        })
        .done(function(data) {
            $("#result").append("<p>" + data + "</p>");
        })
    });
    </script>
    

    위를 긁어 냈다 index.html
    <h1>Let's Greeting!</h1>
    <form action="" method="post">{% csrf_token %}
        {{ form }}
        <button type="submit">送信</button>
    </form>
    
    <div id="result">
        <!-- Will be replaced with inputed text by Ajax -->
    </div>
    
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script>
    // 送信ボタンにイベントリスナーを設定。内部に Ajax 処理を記述
    $("form").submit(function(event) {
        event.preventDefault();
        var form = $(this);
        $.ajax({
          url: form.prop("action"),
          method: form.prop("method"),
          data: form.serialize(),
          timeout: 10000,
          dataType: "text",
        })
        .done(function(data) {
            $("#result").append("<p>" + data + "</p>");
        })
    });
    </script>
    


    비에ws. py


    FormView을 상속받은 GreetView 하나 정의

    greeting/views.py
    from django.http import HttpResponse
    from django.views.generic import FormView
    
    from . import forms
    
    # Create your views here.
    class GreetView(FormView):
        template_name = 'index.html'  # テンプレート名(htmlファイル名)
        form_class = forms.GreetForm
        success_url = '/greet'
    
        def post(self, request, *args, **kwargs):
            form = self.get_form(self.form_class)
            if form.is_valid():
                if request.is_ajax():
                    """Ajax 処理を別メソッドに切り離す"""
                    print('### Ajax request')
                    return self.ajax_response(form)
                # Ajax 以外のPOSTメソッドの処理
                return super().form_valid(form)
            # フォームデータが正しくない場合の処理
            return super().form_invalid(form)
    
        def ajax_response(self, form):
            """jQuery に対してレスポンスを返すメソッド"""
            name = form.cleaned_data.get('name')
            return HttpResponse(f'こんにちは、{name}さん!')
    

    그건 그렇고


    views.py 내의 if request.is_ajax():에 대해서, 공식 문서에는 이하와 같다.

    참조 - 요청 및 응답 객체 | 장고 문서 | 장고

    (한나리 일본어 번역)
    HttpRequest.is_ajax()
    
    HTTP_X_REQUESTED_WITHヘッダの'XMLHttpRequest'文字列で
    リクエストがXMLHttpRequest経由によるものかどうかをチェックし、Trueを返します。
    多くのモダンなJavaScriptライブラリはこのヘッダを送信します。
    

    즉, 이 메소드는 요구 헤더의 HTTP_X_REQUESTED_WITHXMLHttpRequest 가 세트 되는 경우에게만 사용할 수 있다.
    jQuery는 이것을 제대로 세트 해주는 것 같습니다.
    ※jQuery를 사용하지 않는(원래의 JavaScript)로 조금 시험했는데 능숙하지 않았습니다.
  • 검증 코드
  • views.pyGreetView를 다음과 같이 재작성하여 요청 헤더를 들여다 본다.
    class GreetView(FormView):
        template_name = 'greet.html'
        form_class = forms.GreetForm
        success_url = '/greet'
    
        def post(self, request, *args, **kwargs):
            # ★追加
            for k, v in request.META.items():
                print(k, v)
            # ...(以下同様)
    
  • 결과

  • ※디버그 모드라면 대량의 리퀘스트 헤더가 모두 출력되므로 발췌
    ...
    HTTP_ACCEPT text/plain, */*; q=0.01
    HTTP_X_REQUESTED_WITH XMLHttpRequest  # <= これ
    HTTP_USER_AGENT Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
    ...
    

    요약



    이상, 범용 뷰에 의한 Django의 Ajax 샘플을 기재했다.
    다른 기사보다 간결하게 구현할 수 있다고 생각합니다.
    그 외에도 StreamingHttpResponse와 결합하면 무엇을 할 수 있는지 시도하고 싶습니다.

    좋은 웹페이지 즐겨찾기