Django 和 DjangoCMS 视图管理
Django and DjangoCMS View Management
我正在尝试了解一般的 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视图。我不懂为什么。有人能告诉我为什么吗?在浏览器中,页面看起来和工作正常。但是,我希望视图是来自应用程序的视图,后者仅使用一些通用模板。
CMS url从这里开始; https://github.com/divio/django-cms/blob/develop/cms/urls.py
最重要的一点是 details
视图;
https://github.com/divio/django-cms/blob/develop/cms/views.py#L38
除了一些实用函数 (here),CMS 基本上会尝试从提供的 slug(url 路径)中获取页面对象。
通常在 django-cms project, applications such as your video_uploader
and user_accounts
are connected to CMS pages via apphooks
(docs).
内
您所展示的是您的应用程序模板扩展了一个模板,我假设该模板设置为 CMS 模板,base.html
。基本模板是否包含 CMS 工具栏?我怀疑您通过扩展模板引起了冲突,因为您说过另一个自定义视图没有扩展同一个模板。
使用自己的 URL 将您自己的应用程序硬编码到项目中而不使用 CMS apphooks 并没有什么错,但如果您这样做,只需将所有内容隔离开来,确保模板不会拉入系统的CMS端。
要回答有关应用程序链接页面的 URL 的问题,您可以在模板中使用一些变量赋值。例如,我有一个我无法保证已安装的图库应用程序;
{% page_url "gallery" as gallery_url %}
这可能 return 没有值,因此它可以设置为 href
不会做任何事情,或者您可以在条件块中使用它;
{% if gallery_url %}
<a href="{{ gallery_url }}">
Gallery
</a>
{% endif %}
我正在尝试了解一般的 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视图。我不懂为什么。有人能告诉我为什么吗?在浏览器中,页面看起来和工作正常。但是,我希望视图是来自应用程序的视图,后者仅使用一些通用模板。
CMS url从这里开始; https://github.com/divio/django-cms/blob/develop/cms/urls.py
最重要的一点是 details
视图;
https://github.com/divio/django-cms/blob/develop/cms/views.py#L38
除了一些实用函数 (here),CMS 基本上会尝试从提供的 slug(url 路径)中获取页面对象。
通常在 django-cms project, applications such as your video_uploader
and user_accounts
are connected to CMS pages via apphooks
(docs).
您所展示的是您的应用程序模板扩展了一个模板,我假设该模板设置为 CMS 模板,base.html
。基本模板是否包含 CMS 工具栏?我怀疑您通过扩展模板引起了冲突,因为您说过另一个自定义视图没有扩展同一个模板。
使用自己的 URL 将您自己的应用程序硬编码到项目中而不使用 CMS apphooks 并没有什么错,但如果您这样做,只需将所有内容隔离开来,确保模板不会拉入系统的CMS端。
要回答有关应用程序链接页面的 URL 的问题,您可以在模板中使用一些变量赋值。例如,我有一个我无法保证已安装的图库应用程序;
{% page_url "gallery" as gallery_url %}
这可能 return 没有值,因此它可以设置为 href
不会做任何事情,或者您可以在条件块中使用它;
{% if gallery_url %}
<a href="{{ gallery_url }}">
Gallery
</a>
{% endif %}