django URL 모드 분석

16511 단어 Djangodjangourl
차리다
먼저 Django 프로젝트를 새로 만듭니다.
django-admin startproject urlTest
#   manage.py     
./manage.py startapp app1
./manage.py startpap app2

이때 우리는 urlTest라는 프로젝트를 새로 만들었는데 그 중 두 모듈의 이름은 각각 app1과 app2이다.(트리 디렉토리 구조는 다음과 같다)
.
├── app1
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── app2
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── manage.py
└── urlTest
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

settings에서.py에서 우리는 다음과 같은 것을 볼 수 있다.
ROOT_URLCONF = 'urlTest.urls'
#         url   urlTest    urls.py   ,

urls.py는 기본적으로 관리자 모듈의 URL을 추가합니다:
#   urlTest.urls.py 
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

즉, 모든 URL이 지정한view 함수에 비추고,views에서 정의한 함수는 리퀘스트를 받아들이고,response를 되돌려줍니다.만약view의 작업 원리에 대해 잘 모르면, 여기request-response를 참고하십시오.
      

정규 표현식과 명명 그룹
먼저 app1 모듈에서 정규 표현식을 통해 동적 일치하는 년, 년, 년, 년, 일 유형의 URL을 구분합니다.기본적으로 app1 모듈에는 urls가 없습니다.py 파일, 우리가 새로 만든 후에 urlTest의urls가 필요합니다.py 더하기:
url(r'^app1/', include('app1.urls'))
#      app1   urls.py  

다음은 새 app1 모듈 아래의urls입니다.py에 동적 정규 표현식 쓰기:
#  app1.urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index),
    url(r'^([0-9]{4})/$', views.pattern1),
    url(r'^([0-9]{4})/(0?[1-9]|1[0-2])/$', views.pattern2),
    url(r'^([0-9]{4})/(0?[1-9]|1[0-2])/(0?[1-9]|[1-2][0-9]|3[0-1])/$', views.pattern3),
    #    ^ $    ,             
]

나는 크로스바 "/"를 연월일을 분할하는 기호로 사용하는데, 왜 크로스바 앞에 원괄호를 붙여야 합니까?동그란 괄호를 붙일 때django는 URL에서 이 값을 포획하여 대응하는views 함수에 전달할 수 있기 때문에 당연히 위치 참조를 사용한다.URL에 따라 지정한views 함수가 일치하면 HttpResponse로 돌아갑니다.
#  app1.views

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.


def index(request):
    return HttpResponse('index', 'text/plain')


def pattern1(request, year):
    return HttpResponse(year, 'text/plain')


def pattern2(request, year, month):
    return HttpResponse(year + month, 'text/plain')


def pattern3(request, year, month, date):
    return HttpResponse(year + month + date, 'text/plain')

방금 우리가 원괄호를 사용하여 전삼을 할 때 위치전삼이었는데 만약에 우리가 키워드전삼을 사용하고 싶을 때 어떻게 해야 하나요?이때 우리는 이름 그룹을 사용했다. 이름 그룹의 정규 표현식 문법은 (?Ppattern)이고 그 중에서name는 매개 변수를 전달하는 이름을 가리키며pattern은 일치하는 모델을 가리킨다.따라서 다음 코드는 이전의 정규 표현식 + 괄호와 완전히 같은 효과가 있습니다.
#  app1.urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index),
    url(r'^(?P[0-9]{4})/$', views.pattern1),
    url(r'^(?P[0-9]{4})/(?P0?[1-9]|1[0-2])/$', views.pattern2),
    url(r'^(?P[0-9]{4})/(?P0?[1-9]|1[0-2])/(?P0?[1-9]|[1-2][0-9]|3[0-1])/$', views.pattern3),
]

마지막으로views 함수에 있는 매개 변수는 기본 매개 변수를 사용할 수 있고 정규 표현식으로 매개 변수를 포획하지 않는 설정을 할 수 있습니다. (예를 들어 문법 (?:...)
URL 파라미터를 포획하는 것 이외에, 우리는 URL 함수를 통해view 함수에 추가 데이터를 직접 전송할 수 있다.
# urls.py
#   index url
url(r'^$', views.index, {'string': 'Hello World!'})

# views.py
def index(request, string):
    return HttpResponse(string, 'text/plain')


만약include 함수를 포함하는 url 함수에서 추가 데이터를 전송한다면 추가 데이터는 포함된urls에 전송됩니다.py의 줄마다 url 함수에 있습니다.
URL 모드 및 네임스페이스
url patterns에 있는 모든 url 함수는 URL 모드입니다.django에서 클래스django를 사용합니다.core.urlresolvers.RegexURLPattern으로 표시됩니다.
url patterns는 하나의 URL 분해기(url resolver)를 대표하고,include 함수를 사용하여 다른 URL 설정 모듈을 포함하는 것도 하나의 URL 분해기로 해석하고,django에서는 클래스django를 사용한다.core.urlresolvers.RegexURLResolver 로 표시됩니다.
명명 공간은 주로 두 가지로 나뉘는데 그것이 바로 실례 명명 공간(instance namespace)과 응용 명명 공간(application namespace)이다.
왜 명명 공간이 필요합니까?이전에 URL 검색을 통해 URL 모드의name 속성을 통해 검색 표시를 했지만,name 속성은 중복되기 쉬우며 복원에 불리합니다. URL 설정 모듈을 여러 번 배치해야 할 때 간단한name 속성을 통해 표시할 수 없습니다.
어떻게 실례 명명 공간을 설정하고 응용 명명 공간을 합니까?
# include   API
include(arg, namespace=None, app_name=None)
# namespace        ,app_name        
#      app_name,     ,        
if app_name and not namespace:
    raise ValueError('Must specify a namespace if specifying app_name.')

일반적으로 같은 응용 프로그램의 서로 다른 실례는 같은 응용 명칭 공간을 가져야 하지만, 이것은 서로 다른 응용 프로그램이 같은 실례 명칭 공간을 사용할 수 있다는 것을 의미하지 않는다. 왜냐하면 실례 명칭 공간은 모든 프로젝트에서 유일하기 때문이다.
URL 역해석
URL 역방향 해석은 일반적으로reverse 함수와 템플릿의 URL 표시를 통해 이루어진다.먼저 django 공식 문서에서 URL이 역방향으로 해석되는 메커니즘을 살펴보겠습니다.
Reversing namespaced URLs When given a namespaced URL (e.g. ‘polls:index’) to resolve, Django splits the fully qualified name into parts and then tries the following lookup:
  • First, Django looks for a matching application namespace (in this example, ‘polls’). This will yield a list of instances of that application.
  • If there is a current application defined, Django finds and returns the URL resolver for that instance. The current application can be specified with the current_app argument to the reverse() function. The url template tag uses the namespace of the currently resolved view as the current application in a RequestContext. You can override this default by setting the current application on the request.current_app attribute.
  • If there is no current application. Django looks for a default application instance. The default application instance is the instance that has an instance namespace matching the application namespace (in this example, an instance of polls called ‘polls’).
  • If there is no default application instance, Django will pick the last deployed instance of the application, whatever its instance name may be.
  • If the provided namespace doesn’t match an application namespace in step 1, Django will attempt a direct lookup of the namespace as an instance namespace.

  • 마지막 보기 이름이name 표시로 식별되는 것을 제외하고 이전의 모든 이름은 응용 이름 공간으로 식별되었다(제1조). 부합되는 응용 이름 공간을 찾지 못하면 직접 실례 이름 공간으로 식별한다(제5조).응용 네임스페이스를 식별할 때 현재 응용 프로그램에 정의가 있는지 확인(즉current app, 여기는 오해를 일으키기 쉽다. 이 현재 응용 프로그램은 네임스페이스가 아니라 정반대이다. 반대로 네임스페이스를 가리킨다). 정의되면 이전에 확인된 응용 네임스페이스의 소속 네임스페이스 목록에서current 를 직접 찾는다.app의 값(제2조).인스턴스 네임스페이스 목록에서 current 를 찾을 수 없는 경우app의 값입니다. 기본 실례 이름 공간, 즉 응용 이름 공간과 같은 실례 이름 공간을 찾습니다.(제3조) 기본 실례 이름 공간도 찾지 못하면,django는 마지막 배치된 실례 이름 공간의 URL을 되돌려줍니다.(제4조)
    우리는 구체적인 예를 통해 역해석 메커니즘을 설명하자.이전의 예에서 app1 모듈과 app2 모듈을 정의하고 각각 두 개의 실례를 생성했다.
    # urlTest.urls.py
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app2/first/', include('app2.urls', namespace='first', app_name='app2')),
        url(r'^app2/second/', include('app2.urls', namespace='second', app_name='app2')),
        url(r'^app1/third/', include('app1.urls', namespace="third", app_name='app1')),
        url(r'^app1/fourth/', include('app1.urls', namespace="fourth", app_name='app1')),
    ]
    
    # app1.views.py
    from django.core.urlresolvers import reverse
    from django.http import HttpResponse
    import pdb
    def index(request, string):
        pdb.set_trace()
        return HttpResponse(string, 'text/plain')
    

    pdb의 테스트 환경에서 우리는reverse 함수를 사용하여 각각 확정한다.
    (Pdb) reverse('first:index')
    u'/app2/first/'
    (Pdb) reverse('second:index')
    u'/app2/second/'
    (Pdb) reverse('third:index')
    u'/app1/third/'
    (Pdb) reverse('fourth:index')
    u'/app1/fourth/'

    인스턴스 네임스페이스가 전체 프로젝트의 URL을 고유하게 식별하는 것을 볼 수 있습니다.
    (Pdb) reverse('app1:index')
    u'/app1/fourth/'
    (Pdb) reverse('app2:index')
    u'/app2/second/'

    우리가 응용 명명 공간을 사용할 때,django 역방향 해석 메커니즘은current 를 제공하지 않습니다app의 경우 기본 실례 이름 공간을 찾을 수 없고 마지막 배치의 실례 이름 공간만 되돌려줍니다.
    (Pdb) reverse('app1:index', current_app='third')
    u'/app1/third/'
    (Pdb) reverse('app1:index', current_app='fourth')
    u'/app1/fourth/'
    (Pdb) reverse('app2:index', current_app='first')
    u'/app2/first/'
    (Pdb) reverse('app2:index', current_app='second')
    u'/app2/second/'

    인스턴스 네임스페이스가 제공된 후에는 응용 네임스페이스를 사용하더라도 URL을 고유하게 식별할 수 있습니다.마지막으로 기본 실례 이름 공간을 다시 추가합니다.
    # urlTest.urls.py
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app2/default/', include('app2.urls', namespace='app2', app_name='app2')),
        url(r'^app2/first/', include('app2.urls', namespace='first', app_name='app2')),
        url(r'^app2/second/', include('app2.urls', namespace='second', app_name='app2')),
        url(r'^app1/default/', include('app1.urls', namespace="app1", app_name='app1')),
        url(r'^app1/third/', include('app1.urls', namespace="third", app_name='app1')),
        url(r'^app1/fourth/', include('app1.urls', namespace="fourth", app_name='app1')),
    ]
    
    
    # pdb
    (Pdb) reverse('app1:index')
    u'/app1/default/'
    (Pdb) reverse('app2:index')
    u'/app2/default/'

    마지막으로 주의해야 할 것은 서로 다른 응용 프로그램에서 같은 실례가 있을 수 있다고 생각하지 마라.namespace는 반드시 unique이어야 한다!
    이 글은 순전히 개인의 견해에 속하니, 잘못이 있으면 삼가 가르침을 바랍니다.

    좋은 웹페이지 즐겨찾기