Python3/Django

[Django] drf-yasg가 적용되지 않을때 + ImportError: cannot import name 'url' from 'django.conf.urls' + frozen importlib

Razelo 2022. 8. 18. 15:21

Django 를 사용해서 api 개발을 하던 중 api 스펙을 자동으로 생성해주는 drf-yasg 를 사용하려고 했다. 

 

그런데 계속 frozen importlib 에러가 지속적으로 발생했고 django.conf.urls 에서 url 을 import 할 수 없다는 에러가 발생했다. 근데 당시에는 너무 바쁘고 일이 많아서 api 자동 생성을 후순위로 밀어두고 기능 개발을 빠르게 진행했었다. 

 

그러다가 다시 api 를 살펴볼 일이 생겼는데 아예 오늘 drf-yasg 오류를 잡고 api generation을 끝내자고 생각해서 문제를 해결하게 되었다. 

 

우선 ImportError: cannot import name 'url' from 'django.conf.urls' 는 버전 이슈다. 

스택오버플로우를 참고한 결과 아래와 같은 답변을 찾아낼 수 있었다. 

 

django.conf.urls.url() was deprecated in Django 3.0, and is removed in Django 4.0+.

 

즉 Django 4.0으로 버전이 향상되면서 django.conf.urls.url() 이 폐기수순을 밟게 된 것이다. 

 

그렇다면 어떻게 해결하면 될까? 사실 간단하다. django.conf.urls.url 을 사용하지 않으면 된다... (?)

 

자 그런데 이 외에 좀 더 해줘야할 일들이 몇가지 더 있다. 그냥 사용하지 않는 것보다 좀 더 나이스하게 해결할 수 있는 방법이 존재한다. 

 

re_path를 사용하면 된다. 

 

The easiest fix is to replace url() with re_path()re_path uses regexes like url, so you only have to update the import and replace url with re_path.

 

위 답변처럼 그냥 url 을 re_path로 바꿔서 사용하면 된다. 그러기 위해서는 우선 아래와 같이 import 를 진행해보자. (아 참고로 include 는 쓸사람은 쓰고 안쓸 사람은 안써도 된다. 난 옆에 같이 적어놔서 그냥 re_path 만 추가해서 적어줬다.)

from django.urls import include, re_path

 

위와 같이 re_path 를 import 해주고 여지껏 사용한 url 을 모두 re_path 로 바꿔주자. 참고로 아래와 같이 진행하면 된다는 뜻이다. (참고로 urls.py에 적어줘야 한다.)

from django.contrib import admin
from django.urls import path, include

# django api spec generator 
from rest_framework import permissions
from django.urls import include, re_path
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
   openapi.Info(
      title="Snippets API",
      default_version='v1',
      description="Test description",
      terms_of_service="https://www.google.com/policies/terms/",
      contact=openapi.Contact(email="contact@snippets.local"),
      license=openapi.License(name="BSD License"),
   ),
   public=True,
   permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
    
    # swagger path 
    re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
    re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

 

그리고 가장 중요한건 다음이다.

 

이 구문이 존재한다면 지워줘야 한다. 이게 근본적인 문제다. 이걸 없애주지 않으면 frozon importlib 문제가 해결되지 않는다. 

from django.conf.urls import url

사실은 위 구문때문에 ImportError: cannot import name 'url' from 'django.conf.urls'  해당 에러가 발생하는 것이다.

 

그렇다면 위에서 re_path 를 적용한건 왜 그랬을까?

 

굳이 적용하지 않아도 될까? 굳~이 적용하지 않아도 되긴 한다. 

 

그런데 re_path 를 적용하지 않으면 아래 Warnings 를 만나게 될 것이다.

 

그래서 없애주었다. Django 4.0 에서 deprecated 된 걸 굳이 쓸 필요는 없다. 

?: (2_0.W001) Your URL pattern '^redoc/$' [name='schema-redoc'] has a route that contains '(?P<', 
begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().
?: (2_0.W001) Your URL pattern '^swagger(?P<format>\.json|\.yaml)$' [name='schema-json'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when 
migrating to django.urls.path().
?: (2_0.W001) Your URL pattern '^swagger/$' [name='schema-swagger-ui'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().

 

 

참고한 스택 오버플로우를 첨부한다. 많은 도움이 되었다. 감사합니다. 

 

https://stackoverflow.com/questions/70319606/importerror-cannot-import-name-url-from-django-conf-urls-after-upgrading-to

 

ImportError: cannot import name 'url' from 'django.conf.urls' after upgrading to Django 4.0

After upgrading to Django 4.0, I get the following error when running python manage.py runserver ... File "/path/to/myproject/myproject/urls.py", line 16, in <module> from d...

stackoverflow.com

 

반응형