您好,登錄后才能下訂單哦!
作者: 何全,github地址: https://github.com/hequan2017 QQ交流群: 620176501
通過此教程完成從零入門,能夠獨立編寫一個簡單的CMDB系統。
目前主流的方法開發方式,分為2種:mvc 和 mvvc方式。本教程為 mvc 方式,即 django負責渲染html。后面會推出 mvvc(前后端分離)的入門教程。
教程項目地址: https://github.com/hequan2017/husky/
教程文檔地址: https://github.com/hequan2017/husky/tree/master/doc
首頁
pycharm : 菜單欄 tools --> 選擇 run manage.py task
manage.py@husky > startapp system # 創建一個APP ,用來管理系統
具體內容請看實際頁面,下面只是把重點代碼 進行展示。
from django.contrib import admin
from django.urls import path
from system.views import index
from django.conf.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
path('index', index, name="index"),
path('system/', include('system.urls', namespace='system')), ## 引入 system 的urls 文件
]
system/__init.py 新建空白文件
@login_required(login_url="/system/login")
def index(request):
"""
首頁
:param request:
:return:
"""
return render(request, 'system/index.html',{}) #render 結合一個給定的模板和一個給定的上下文字典,并返回一個渲染后的 HttpResponse 對象。
繼承user表結構,重建user表
?用?一個 Python 類來描述數據表, 我們 稱之為 模型(model) 。 運?用這個類,你可以通過簡單的
Python 的代碼來創建、檢索、更更新、刪除 數據庫中的記錄?而?無需寫?一條?又?一條的SQL語句句,這
就是傳說中的ORM(Object Relation Mapping)
from django.db import models
from django.contrib.auth.models import AbstractUser
class Users(AbstractUser): # AbstractUser 重寫 user 需要集成表
"""
基于django表 添加字段 , 如有需要調用user的情況,請使用此表
"""
position = models.CharField(max_length=64, verbose_name='職位信息', blank=True, null=True)
avatar = models.CharField(max_length=256, verbose_name='頭像', blank=True, null=True)
mobile = models.CharField(max_length=11, verbose_name='手機', blank=True, null=True)
class Meta:
db_table = 'users'
verbose_name = '用戶信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
因為更改了默認的user表,需要先把庫刪了。再進行重建。
drop database husky;
create database husky;
pycharm : 菜單欄 tools --> 選擇 run manage.py task
makemigrations 生成數據文件
migrate 根據文件,執行生成表結構
createsuperuser
import sys
INSTALLED_APPS = [ # 這里填寫 創建的app ,結構為, 一個項目 可以有多個APP
"system",
'bootstrap3'
]
AUTH_USER_MODEL = 'system.users'
AUTHENTICATION_BACKENDS = ('system.views.CustomBackend',) ## 重新登錄驗證,增加郵箱名字也可以用作登錄
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_COOKIE_SAMESITE = 'Lax'
CSRF_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_AGE = 432000
LOGIN_URL = '/auth/login'
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = False
USE_TZ = True
DATETIME_FORMAT = 'Y-m-d H:i:s'
DATE_FORMAT = 'Y-m-d'
# logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '[argus] %(levelname)s %(asctime)s %(module)s %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'stream': sys.stdout,
'formatter': 'verbose'
},
},
'loggers': {
'tasks': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
'asset': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
},
}
# 表格table
PAGINATION_SETTINGS = {
'PAGE_RANGE_DISPLAYED': 3,
'MARGIN_PAGES_DISPLAYED': 2,
'SHOW_FIRST_PAGE_WHEN_INVALID': True,
}
# 表格table 一頁 展示數據
DISPLAY_PER_PAGE = 15
View 包含了了項?目的業務邏輯,我們稱之為視圖,也是我們開發過程中主要編寫的內容
def login_view(request):
"""
登錄
:param request: username,password
:return:
"""
error_msg = "用戶名或密碼錯誤,或者被禁用,請重試"
if request.method == "GET":
return render(request, 'system/login.html', {'error_msg': error_msg, })
if request.method == "POST":
u = request.POST.get("username")
p = request.POST.get("password")
user = authenticate(request, username=u, password=p)
if user is not None:
if user.is_active:
login(request, user)
request.session['is_login'] = True
login_ip = request.META['REMOTE_ADDR']
return redirect('/index') ## 重定向到的一個具體的網址
else:
return render(request, 'system/login.html', {'error_msg': error_msg, })
else:
return render(request, 'system/login.html', {'error_msg': error_msg, })
class CustomBackend(ModelBackend):
"""
用戶名字/郵箱名字 登錄
:param request:
:return:
"""
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = Users.objects.get(Q(username=username) | Q(email=username))
if user.check_password(password):
return user
except Exception as e:
logger.error(e)
return None
指出了了什什么樣的 URL 調?用什什么的視圖。 在這個例例?子中 /latest/ URL 將會調?用 latest_books() 這
個函數。 換句句話說,如果你的域名是example.com,任何?人瀏覽?網址 http://example.com/latest/ 將
會調?用 latest_books()這個函數返回結果給?用戶
from django.urls import path
from system.views import login_view
app_name = "system"
urlpatterns = [
path('login', login_view, name="login")
]
簡單來說就是html 模板,它描述了了項?目的界?面結構。 模板引擎也內置了了?一些tag 。
登錄不繼承 base.html ,為一個單獨頁面
<h4>歡迎登錄 系統</h4>
<form class="m-t" role="form" action="{% url "system:login" %}" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" name="username" class="form-control" placeholder="用戶名" required="">
</div>
<div class="form-group">
<input type="password" name="password" class="form-control" placeholder="密碼" required="">
</div>
<button type="submit" class="btn btn-primary block full-width m-b">登錄</button>
<a href="#">
<span > {{ error_msg }}</span><br>
不推薦使用IE/360瀏覽器(兼容模式)瀏覽!<br />
</a>
<div id="login_container"></div>
</form>
def logout_view(request):
"""
注銷
:param request:
:return:
"""
logout(request)
return redirect('system:login')
path('logout', logout_view, name="logout"),
<li>
<a href="{% url "system:logout" %}">
<i class="fa fa-sign-out"></i> 注銷
</a>
</li>
用戶表單是Web端的一項基本功能,大而全的Django框架中自然帶有現成的基礎form對象,本文就Python的Django框架中forms表單類的使用方法詳解。
from django import forms
class UserPasswordForm(forms.Form):
old_password = forms.CharField(max_length=128, widget=forms.PasswordInput, label='舊密碼')
new_password = forms.CharField(min_length=8, max_length=128, widget=forms.PasswordInput, label='新密碼',
help_text="* 你的密碼必須包含至少 8 個字符,不能是大家都愛用的常見密碼,不能全部為數字")
confirm_password = forms.CharField(min_length=8, max_length=128, widget=forms.PasswordInput, label='確認密碼',
help_text="* 和上面密碼一致")
def __init__(self, *args, **kwargs):
self.instance = kwargs.pop('instance')
super().__init__(*args, **kwargs)
def clean_old_password(self):
old_password = self.cleaned_data['old_password']
if not self.instance.check_password(old_password):
raise forms.ValidationError('舊密碼錯誤')
return old_password
def clean_confirm_password(self):
new_password = self.cleaned_data['new_password']
confirm_password = self.cleaned_data['confirm_password']
if new_password != confirm_password:
raise forms.ValidationError('新密碼與確認密碼不一致')
return confirm_password
def save(self):
password = self.cleaned_data['new_password']
self.instance.set_password(password)
self.instance.save()
return self.instance
system/views.py
class UserPasswordUpdateView(LoginRequiredMixin, UpdateView):
"""
修改密碼
:param request:
:return:
"""
template_name = 'system/password.html'
model = Users
form_class = UserPasswordForm
success_url = reverse_lazy('system:logout')
def get_object(self, queryset=None):
return self.request.user
def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs)
def get_success_url(self):
return super().get_success_url()
path('password_update', UserPasswordUpdateView.as_view(), name="password_update"),
templates/system/password.html
<div class="wrapper wrapper-content animated fadeInRight">
<form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger" >
{{ form.non_field_errors }}
</div>
{% endif %}
<div class="form-group">
<div class="col-sm-10 col-sm-offset-0"> {{ msg }}
{% bootstrap_field form.old_password layout="horizontal" %}
{% bootstrap_field form.new_password layout="horizontal" %}
{% bootstrap_field form.confirm_password layout="horizontal" %}</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-3">
<button id="submit_button" class="btn btn-primary" type="submit">提交</button>
<button class="btn btn-white" type="reset">重置</button>
</div>
</div>
</form>
</div>
后臺界面配置文件,每個APP 可以創建一個
from django.contrib import admin
from system.models import Users
from django.contrib.auth.admin import UserAdmin
class UsersAdmin(UserAdmin):
fieldsets = (
(None, {'fields': ('username', 'password')}),
('基本信息', {'fields': ('first_name', 'last_name', 'email')}),
('權限', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
('登錄時間', {'fields': ('last_login', 'date_joined')}),
('其他信息', {'fields': (
'position', 'avatar', 'mobile',)}),
)
@classmethod
def show_group(self, obj):
return [i.name for i in obj.groups.all()]
@classmethod
def show_user_permissions(self, obj):
return [i.name for i in obj.user_permissions.all()]
list_display = ('username', 'show_group', 'show_user_permissions')
list_display_links = ('username',)
search_fields = ('username',)
filter_horizontal = ('groups', 'user_permissions')
admin.site.register(Users, UsersAdmin)
admin.site.site_header = '管理后臺'
admin.site.site_title = admin.site.site_header
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。