[Mobilar] 01 - Multiple Users: user registration, login and logout
R&D
一、调查取证
Ref: Many sites, one Wagtail: a detailed walkthrough
That's possible but Wagtail isn't set up to isolate a user that completely. From the post: "Users in this group will be able to see the other sites' content in the explorer menu, but they won't be able to create, edit, or delete any content in them." Clients probably wouldn't want to have to see other clients' junk, though. For the most part, Wagtail's user permissions are useful for isolating user's different responsibilities in a single large organization, not for letting multiple organizations share the same Wagtail install.
A better way to think about Wagtail's multi-site functionality is with a single organization which might have multiple brands like, say, Kellogg's cereal. You have lots of domains like frootloops.com, frostedflakes.com, frostedminiwheats.com, etc. but don't want to maintain a different server or CMS installation for each, so you could bring them all into a single Wagtail install with a different site tree for each. You could treat them as totally separate entities, each with different content types and templates, or you could have certain parts of the sites share content types, templates, and other features. It makes sense to combine some content given this setup, like an "About Kelloggs" page, for instance, so you're not making N updates for each brand -- just update once and have that content pulled in from Wagtail's snippets repository (or something).
From: slack of Wagtail by
I had a somewhat similar requirement a few years ago and was able to use permissions to give each user access to only their pages - and now that there is a view permission for collections (as of 2.12), you can give each user their own collection for uploading images and documents.
目前练习使用的是 v2.5.1。
[问]
hi, @Cynthia Kiser, I see the latest version is 2.12rc1, and "Added a distinct 'choose' permission for images and documents" (Robert Rollins)
this is a real new feature, but only for images and documents, not for pages.
My understanding is that, to implement Hadi's requirement,
(1) use permissions to give each user access to only their pages
(2) use the new feature of 2.12rc1 on images and documents.so that, each user will have their own pages, images, and documents. Right?
[答]
Yes that is correct. If you give each user edit permission on their profile page they can manage that page and no others. If you give them add permission on the profile page they can make subpages under their profile
[答]
Hi @Jeff! In the latest version of Wagtail, there is a "choose" permission that you can use to make a group of users able to only choose images/documents from specific collections. Wagtail isn't quite there yet in terms of 'fully isolated multi-tenancy' so some things might not be possible without patching. You may find the following issue helpful: https://github.com/wagtail/wagtail/issues/4288
Ref: Wagtail per page user permission
貌似通过 装饰器
Ref: use permissions to give each user access to only their pages
貌似通过 装饰器
How to modify wagtail CMS so that any user can post blog posts under their own blog
答案是不能,方案选型存在风险。
三、前后端分离
Build a YouTube bookmarking site with Vue.js【有点类似】
普通用户 - 注册
Ref: Python Django Tutorial: Full-Featured Web App Part 6 - User Registration
文件 settings.py
INSTALLED_APPS = [ 'blog.apps.BlogConfig', 'users.apps.UsersConfig', # <---- 其实就是 文件夹路径,文件路径,类名
... ...
一、跨站请求伪造
网页 template/users/register.html
<form method="POST">{% csrf_token %} # <---- 针对 form 会考虑的一个 feature
-
是什么
Ref: 跨站请求伪造—CSRF
-
Cookie 凭证
二、路由设置
from users import views as user_views urlpatterns = [ path('admin/', admin.site.urls), path('register/', user_views.register, name='register'), path('', include('blog.urls')), ]
三、View 设置
from django.shortcuts import render, redirect from django.contrib import messages from .forms import UserRegisterForm def register(request): if request.method == 'POST': # 其中,使用了 UserCreationForm 创建了 form。 form = UserRegisterForm(request.POST) # 处理发来的 request.POST,后台注册成功后,则 is_valid = true if form.is_valid(): form.save() username = form.cleaned_data.get('username') messages.success(request, f'Account created for {username}!') # <---- 作为提示展示给用户 return redirect('blog-home') else: form = UserRegisterForm() return render(request, 'users/register.html', {'form': form})
注册结果展示,tip的内容有点不同,但效果一样。
四、美化 form
pip install django-crispy-forms
INSTALLED_APPS = [ 'blog.apps.BlogConfig', 'users.apps.UsersConfig', 'crispy_forms' # <----
CRISPY_TEMPLATE_PACK = 'bootstrap4'
{% extends "blog/base.html" %} {% load crispy_forms_tags %} {% block content %} <div class="content-section"> <form method="POST"> {% comment %} 防止跨站请求伪造 {% endcomment %} {% csrf_token %} <fieldset class="form-group"> <legend class="border-bottom mb-4">Join Today</legend> {{ form|crispy }} </fieldset> <div class="form-group"> <button class="btn btn-outline-info" type="submit">Sign Up</button> </div> </form> <div class="border-top pt-3"> <small class="text-muted"> Already Have An Account? <a class="ml-2" href="#">Sign In</a> </small> </div> </div> {% endblock content %}
间接地 达到 css的效果。
{{ form.as_p }}
更改为
{{ form|crispy }}
1) {{ form.as_table }}
将表单渲染成一个表格元素,每个输入框作为一个<tr>
标签
2) {{ form.as_p }}
将表单的每个输入框包裹在一个<p>
标签内 tags
3) {{ form.as_ul }}
将表单渲染成一个列表元素,每个输入框作为一个<li>
标签
普通用户 - 登录与退出
一、登录
{% extends "blog/base.html" %} {% load crispy_forms_tags %} {% block content %} <div class="content-section"> <form method="POST"> {% csrf_token %} <fieldset class="form-group"> <legend class="border-bottom mb-4">Log In</legend>
{{ form|crispy }} </fieldset> <div class="form-group"> <button class="btn btn-outline-info" type="submit">Login</button> # <---- </div> </form> <div class="border-top pt-3"> <small class="text-muted"> Need An Account? <a class="ml-2" href="{% url 'register' %}">Sign Up Now</a> </small> </div> </div> {% endblock content %}
-
跳转到 user profile 界面
# Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' CRISPY_TEMPLATE_PACK = 'bootstrap4'
# 登录的跳转控制 LOGIN_REDIRECT_URL = 'blog-home' # 来源于 urls.py相关的路由定义中 LOGIN_URL = 'login'
二、页面权限
-
登录后链接的改变
<!-- Navbar Right Side --> <div class="navbar-nav"> {% if user.is_authenticated %} <a class="nav-item nav-link" href="{% url 'profile' %}">Profile</a> <a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a> {% else %} <a class="nav-item nav-link" href="{% url 'login' %}">Login</a> <a class="nav-item nav-link" href="{% url 'register' %}">Register</a> {% endif %} </div>
-
登录后才能进入的页面该如何显示
http://127.0.0.1:8000/login/?next=/profile/
LOGIN_REDIRECT_URL = 'blog-home'
LOGIN_URL = 'login'
-
Profile 的实现
@login_required def profile(request): return render(request, 'users/profile.html')
End.