Я пытаюсь понять, как Django в целом и DjangoCMS в частности управляют представлениями.
У меня есть следующее в urls.py
проекта:
urlpatterns = [
path('admin/', admin.site.urls),
path('video/', include('video_uploader.urls')),
path('user/', include('user_accounts.urls')),
path('', include('cms.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
То естьпара конкретных маршрутов, а остальные обрабатываются DjangoCMS (cms.urls
).
Внутри одного из приложений (соответствует пути /user/
выше), у меня есть это:
from django.urls import path
from . import views
app_name = 'user_accounts'
urlpatterns = [
path('signup', views.user_signup, name='signup'),
]
Вид этого пути следующий:
def user_signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
print('Is the form valid?')
print(form.is_valid())
if form.is_valid():
user = form.save()
login(request, user)
return redirect('/')
else:
form = UserCreationForm()
return render(request, 'user_accounts/signup.html', {'form': form})
Пока все хорошо. Теперь перейдем к интересным битам.
user_accounts / signup.html
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h2>Sign up</h2>
<form method="post" novalidate>
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-primary">Create an account</button>
</form>
</div>
{% endblock %}
Шаблон выше расширяет base.html
, который является базовым шаблоном длявесь проект. Другими словами, эта форма регистрации встроена в блок содержимого страницы, чтобы сделать приложение единым.
Во время тестирования представления регистрации я пытался сделать следующее:
class SignUpTest(TestCase):
def setUp(self):
url = reverse('user_accounts:signup')
self.response = self.client.get(url)
def test_signup_status_code(self):
self.assertEqual(self.response.status_code, 200)
def test_signup_url_resolves_signup_view(self):
view = resolve('/user/signup/')
print(view)
print(view.func)
print(resolve('/video/'))
print(resolve('/video/').func)
self.assertIs(view.func, user_signup)
Проблема в том, что тест не пройден. Сбой, потому что две функции разные.
> FAIL: test_signup_url_resolves_signup_view
> (user_accounts.tests.SignUpTest)
> Traceback (most recent call last): File
> "/home/user-name/sites/project-web/project/user_accounts/tests.py",
> line 20, in test_signup_url_resolves_signup_view
> self.assertIs(view.func, user_signup) AssertionError: <function details at 0x7f0dc78bf050> is not <function user_signup at
> 0x7f0dc9891200>
Кто они?
Вот отпечатки, которые я получил.
ResolverMatch(func=cms.views.details, args=(), kwargs={'slug': 'user/signup'}, url_name=pages-details-by-slug, app_names=[], namespaces=[])`
`<function details at 0x7f0dc78bf050>
ResolverMatch(func=video_uploader.views.list_videos, args=(), kwargs={}, url_name=list_videos, app_names=['video_uploader'], namespaces=['video_uploader'])`
`<function list_videos at 0x7f0dc8ecf950>
Я использую /video/
путь для печати, потому что это приложение имеет почти такую же настройку, что и рассматриваемое приложение. Основное отличие состоит в том, что первый еще не расширяет шаблон base.html
. Похоже, что представление затем преобразуется в представление, отличное от DjangoCMS.
Как вы можете видеть, представление, которое фактически используется при посещении user/signup/
, является представлением DjangoCMS. Я не понимаю почему. Может кто-нибудь сказать мне, почему? В браузере страница выглядит и работает просто отлично. Тем не менее, я ожидал, что это будет представление из приложения, а последнее просто использует несколько общих шаблонов.