Django知识点
一、Django的優勢
Python的WEB框架有Django、Tornado、Flask 等多種,Django相較與其他WEB框架其優勢為:大而全,框架本身集成了ORM、模型綁定、模板引擎、緩存、Session等諸多功能
二、DJango項目的創建
1)命令行
django-admin startproject sitename # 建項目 python manage.py runserver 0.0.0.0 # 啟動服務 python manage.py startapp appname # 創建app python manage.py syncdb # 建表是的編碼是utf8(后面的版本取消) python manage.py makemigrations # 連接庫 python manage.py migrate # 建表 python manage.py createsuperuser # 創建admin用戶?
2)pycharm
?
?
三、Django的目錄結構
myblog目錄:
項目的一個容器
包含項目的一些基本配置
目錄名稱不建議修改
myblog/wsgi.py (Python web server gateway interface):python 服務器網關接口,python應用與web服務器之間的接口,該文件在項目開發中一般不做修改
urls.py:url配置文件,Django項目中所有地址(頁面)都需要我們自己去配置URL
settings.py:項目的總配置文件,里面包含了數據庫、web應用、時間等各種配置
里面包含:
1)BASE_DIR,項目逇根目錄
2)SECRET_KEY,安全碼,Django生成項目的時候自動生成
3)DEBUG,調試開關,項目發布的時候需要關閉
4)INSTALLED_APPS,自己創建的應用,需要在這里添加注冊
5):MIDDLEWARE,中間件,Django自帶的工具集
6):ROOT_URLCONF,配置URLS的路徑
7):TEMPLATES,模板的配置文件
8):DATABASES,數據庫配置
9):STATIC_URL,靜態文件的地址,Static files (CSS, JavaScript, Images)
init.py:python中聲明模塊的文件,內容默認為空
啟動項目
.python manage.py runserver
四、連接數據庫
注:新建的數據庫要指定utf8格式,否則在建表時(有中文輸入)會出現亂碼
步驟:setting配置數據庫,連接數據庫,建表
1、setting配置DATABASES
?
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql', #數據庫引擎'NAME': 'test', #數據庫名'USER': 'root', #用戶名'PASSWORD': 'root', #密碼'HOST': '', #數據庫主機,默認為localhost'PORT': '', #數據庫端口,MySQL默認為3306'OPTIONS': {'autocommit': True,},}}2、由于Django內部連接MySQL時使用的是MySQLdb模塊,而python3中還無此模塊,所以需要使用pymysql來代替
在項目根目錄下中的__init__.py文件中添加代碼:
# 如下設置放置的與project同名的配置的 __init__.py文件中 import pymysql pymysql.install_as_MySQLdb()3、在setting配置模版文件路徑(把html存放在templates)--默認已配置好
?
TEMPLATE_DIRS = ( os.path.join(BASE_DIR,'templates'), )4、在setting配置靜態文件路徑(把css,js存放在statics)
注:在生產環境下(DEBUG=False),該配置失效
STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)注:在html里應用靜態文件,建議使用模板語言1)在html開頭添加{% load staticfiles %}2)應用靜態文件{% static 'css/reset.css' %}5、當涉及到文件上傳時,在setting配置
注:涉及到文件上傳的upload # 配置上傳文件的路徑 ========================================= MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR,"media") =========================================2)url配置 ================================================================== 舊版本: from django.views.static import serve # 前端顯示出圖片內容,舊版本 from TFF.settings import MEDIA_ROOT# url(r'^madia/(?P<path>.*)$', serve,{"document_root":MEDIA_ROOT}), # 舊版本 ================================================================== # 新版本 from django.conf.urls.static import static from TFF import settingsurlpatterns = []+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) # 在url配置的尾部加一、數據庫的設計(ORM):
思路:分層設計,如下例子
根據app設計(分層設計)uers-用戶管理Course-課程管理organization-機構和教師管理以上的3個app在同一層operation-用戶操作管理 (最上層)1)給每個app的model文件里,建表(關系對象映射):
一般用戶表,都需要繼承Django原本的auth表
1)可以繼承默認生成的user表from django.contrib.auth.models import AbstractUserclass Userprofile(AbstractUser):nick_name = models.CharField(max_length=32,verbose_name=u"昵稱",default=u"")birthday = models.DataField(verbose_name=u"生日",null=True,blank=True)gender = models.CharField(choices=(("male",u"男"),("female",u"女")),default=u"")address = models.CharField(max_length=128,default=u"")mobile = models.CharField(max_length=11,null=True,blank=True)image = models.ImageField(upload_to="image/%Y/%m",default=u"image/default.png",max_length=128)class Meta:verbose_name = "用戶信息"verbose_name_plural = verbose_namedef __unicode__(self): # 定義返回utf8(中文) return self.username注: a)在setting中增加字段 AUTH_USER_MODEL = "users.Userprofile" # users為app的名,Userprofile為數據表的名 b)下面為一些AbstractBaseUser的子類必須定義的關鍵的字段和方法: # 否則會報錯:type object 'UserProfile' has no attribute 'USERNAME_FIELD' USERNAME_FIELD必須設置。 設置認證標識,設置成標識的字段 unique=Trueclass MyUser(AbstractBaseUser):identifier = models.CharField(max_length=40, unique=True)...USERNAME_FIELD = 'identifier'c)用戶重寫: http://www.jianshu.com/p/b993f4feff83User表又如給Course建表:
class Course(models.Model):name = models.CharField(max_length=64,verbose_name=u'課程名稱')org_name = models.ForeignKey(CourseOrg,verbose_name=u'所屬機構',null=True,blank=True)teacher = models.ForeignKey(Teacher,verbose_name=u'課程教師',null=True,blank=True)desc = models.CharField(max_length=256,verbose_name=u'課程描述')is_Adware = models.BooleanField(default=False,verbose_name=u'是否廣告')detail = models.TextField(verbose_name=u'課程詳情')course_type = models.CharField(verbose_name=u'課程類型',default='',max_length=50)degree = models.IntegerField(default=1,choices=((1,'初級'),(2,'中級'),(3,'高級')),verbose_name=u'課程級別')learn_times = models.IntegerField(default=0,verbose_name=u'學習時長')students = models.IntegerField(default=0,verbose_name=u'學習人數')fav_nums = models.IntegerField(default=0,verbose_name=u'收藏人數')image = models.ImageField(upload_to='course/%Y/%m',default='course/default.png',max_length=256,verbose_name=u'課程圖片')click_num = models.IntegerField(default=0,verbose_name=u'點擊人數')add_time = models.DateTimeField(default=datetime.now,verbose_name=u'添加時間')teacher_tellyour = models.CharField(default='',verbose_name=u'老師的講話',max_length=300)work = models.CharField(default='',verbose_name=u'職業',max_length=64)例子2)在setting中增加字段?
在INSTALLED_APPS列表里加載app
3)給app建好需求的表時:
運行命令:
python manage.py makemigrations # 連接庫 python manage.py migrate # 建表附:(重點注意)
附:1、如果解決數據庫輸入中文亂碼的問題1)創建數據庫時create database test default charset=utf8;2)在Django創建數據表示用:python manager.py syncdb # 3.0版本后就沒有了2、每生成一個數據表1)在app目錄下的migrations目錄會生成對應一個記錄文件2)在數據庫中的auth_migration表里也會生成一條對應的數據記錄3、verbose_name 是后臺管理顯示的名字4、def __unicode__(self):return self.name 是后臺管理顯示創建每條數據的名稱注:上面是Python2.0的版本3.0版本是def __str__(self):5、注:涉及到文件上傳的upload# 配置上傳文件的路徑=========================================MEDIA_URL = '/media/'MEDIA_ROOT = os.path.join(BASE_DIR,"media")=========================================二、后臺管理(Django admin和xadmin)---一般用xadmin,功能更強大,智能的管理系統
特點:權限管理少前端樣式快速開發1、設置網站為中文顯示(zh-hans,Asia/Shanghai,USE_TZ=False) # USE_TZ管理寫入數據庫的時區時間2、管理user用戶表1)設置app的admin.py=================================================from .models import UserProfileclass UserProfileAdmin(admin.ModelAdmin):passadmin.site.register(UserProfile,UserProfileAdmin)=================================================另外一個后臺管理構架--xadmin1、安裝 1)pip install xadmin2)源碼安裝(推薦使用),用GitHub依賴包:pip3 install future;pip3 install django-crispy_forms;3)在setting中的applist加上'xadmin','crispy_forms',4) 修改url,把admin ==> xadmin5) 生成xadmin數據表2、xadmin用法--app的model注冊1)在每個app文件夾里新建py文件:adminx.py2)import xadminfrom .models import UserProfile,EmailVerifyRecord,Bannerclass EmailVerifyRecordAdmin(object):list_display = ['email','code','send_type','send_time'] # 展示出來的列search_fields = ['email','code','send_type'] # 搜索欄list_filter = ['email','code','send_type','send_time'] # 過濾器ordering = ['-click_nums'] # 排序readonly_fields = ['fav_nums'] # 設置只讀exclude = ['click_nums'] # 不可見,與readonly_fields有沖突,同一列數據不可同時存在這兩個字段里 xadmin.site.register(EmailVerifyRecord,EmailVerifyRecordAdmin) # 與admin關聯3)注:當有外鍵時:list_filter = ['user__username','fav_id','fav_type','add_time'] # 過濾器有所變量,用雙下劃線3、xadmin后臺管理頁面設置(在user的app設置)1)主題設置==============================================from xadmin import viewsclass BaseSetting(object):enable_themes = True # 顯示主題use_bootswatch = True # 能使用那些主題 xadmin.site.register(views.BaseAdminView,BaseSetting)============================================== 2)網站標題和頁尾標題、model顯示樣式==============================================from xadmin import viewsclass GlobalSetting(object):site_title = "騰飛后臺管理系統"site_footer = "騰飛學習網"menu_style = "accordion"xadmin.site.register(views.CommAdminView,GlobalSetting)==============================================3)model顯示的app名,如何改為中文名a. 在apps.py修改在類中增加 verbose_name = u"用戶操作"b. 在__init__.py 文件增加default_app_config = "users.apps.Usersconfig" # Usersconfig :類名 + config三、每個html頁面與一個view的類一一對應
注:
要用“return HttpResponseRedirect(reverse("index"))”而不用“return render(request,"index.html",{})”原因是:第一種:除了跳轉到頁面,還會執行“頁面對應view方法”,而render不會執行view方法如:登錄與注冊的頁面設置 一、登錄1、網站主頁1)把index.html 放入templates里2)新建靜態文件/static,把css、images、img、js、media放入其內3)設置setting中的靜態文件路徑4)編寫url==================================================from django.views.generic import TemplateViewurl(r'^$',TemplateView.as_view(template_name="index.html"),name="index"),==================================================2、登錄頁面1)把login.html 放入templates里2)編寫user的app中的views文件(寫函數)-- 一般是以類的方式寫==================================================類:from django.contrib.auth import authenticate,login # 用戶驗證函數from django.views.generic.base import View # 編寫類時,一定要繼承該類class UserLogin(View):def get(self,request):return render(request, "login.html", {})def post(self,request):user_name = request.POST.get("username",None)user_pwd = request.POST.get("password",None)result = authenticate(username=user_name,password=user_pwd) # 使字段request.user.is_authenticated變成Trueif result:login(request,result) # 把result寫入requestreturn render(request,"index.html",{"username":result.username}) # result為user該條數據else:return render(request,"login.html",{"meg":"用戶名或密碼錯誤"})============================================================函數:from django.contrib.auth import authenticate,login # 用戶驗證函數;login是生成sessiondef UserLogin(request):if request.method == "POST":user_name = request.POST.get("username",None)user_pwd = request.POST.get("password",None)result = authenticate(username=user_name,password=user_pwd) # 使字段request.user.is_authenticated變成Trueif result:login(request,result) # 把result寫入requestreturn render(request,"index.html",{"username":result.username}) else:return render(request,"login.html",{})elif request.method == "GET":return render(request, "login.html", {})============================================================注:POST要大寫;兩個內置用戶驗證函數authenticate,login3)編寫驗證成功后跳轉頁面的設置(數據交互){% if request.user.is_authenticated %} # 驗證成功后,request.user.is_authenticated為True4)urlurl(r'^login/',user_views.UserLogin.as_view(),name="userlogin") # 類的寫法,多了as_view()url(r'^login/',user_views.UserLogin,name="userlogin") # 函數的寫法3、自定義authenticate類,用戶驗證(原來只支持用戶名登錄,不支持郵箱登錄)1)在app中views文件里重寫authenticate============================================================from django.contrib.auth.backends import ModelBackend # 重寫時一定要繼承這個類from django.db.models import Q # 邏輯and,orclass UserBackend(ModelBackend):def authenticate(self, request, username=None, password=None, **kwargs):try:user = UserProfile.objects.get(Q(username=username)|Q(email=username)) # 或的寫法,and的寫用逗號隔開if user.check_password(password): # 檢查密碼是否正確return userexcept Exception as e:return None============================================================2)在setting中加入AUTHENTICATION_BACKENDS = ("user.views.UserBackend",)4、后臺的Form驗證(有兩種方法)1)在app下新建form.py,內容如下=========================================================方法一:自定義from django import formsclass LoginForm(forms.Form):username = forms.CharField(required=True) # username必須與form表單里定義的name一致password = forms.CharField(required=True,min_length=8) # password必須與form表單里定義的name一致 注:重新定義錯誤信息:error_messages={'required':u"密碼不能為空",'invalid':u"密碼最少8位數"}方法二:引用自帶的(推薦使用,與model結合)class UserAskForm(forms.ModelForm):class Meta:model = UserAskfields = ['name','mobile','course_name']def clean_mobile(self):mobile = self.cleaned_data['mobile']mobile_model = "^1[358]\d{9}$|^147\d{8}$|^176/d{8}$"p = re.compile(mobile_model)if p.match(mobile):return mobileelse:raise forms.ValidationError(u'手機號碼錯誤',code="mobile_invalid")=========================================================2)在view里調用方法一對應的調用:login_form = LoginForm(request.POST) # 獲取一個驗證的大字典,錯誤信息放在errors的健值里if login_form.is_valid(): # 判斷是否驗證成功 方法二對應的調用:userask_form = UserAskForm(request.POST)if userask_form.is_valid():# 把提交數據保存在數據表里,不用在從form表單里提出每個數據,在進行保存(優點)userask_obj = userask_form.save(commit=True) 3)在html調用login_form{% if form_error.errors.password %}errorput{% endif %}{% for key,value in form_error.errors.items %} # 字典循環(items) 二、注冊1、注冊頁面其他的設置類似于登錄頁面。注意:1)、驗證碼(相關操作地址http://django-simple-captcha.readthedocs.io/en/latest/usage.html)2)、驗證碼在view引用時,get方法時:register_form = RegisterForm() # 不需要傳變量def get(self,request):register_form = RegisterForm()return render(request,'register.html',{"register_form":register_form})3)、驗證碼在html引用是:{{ register_form.captcha }}2、后臺邏輯操作===============================================class UserRegister(View):def get(self,request):register_form = RegisterForm()return render(request,'register.html',{"register_form":register_form})def post(self,request):register_form = RegisterForm(request.POST)if register_form.is_valid():user_name = request.POST.get("email",None)user_pwd = request.POST.get("password",None)user_object = UserProfile()user_object.username = user_nameuser_object.email = user_nameuser_object.password = make_password(user_pwd)user_object.save()return render(request,'index.html',{"username":user_name})else:return render(request,'register.html',{"register_form":register_form})===============================================3、實現發送郵箱1)配置setting===========================================EMAIL_HOST = "smtp.126.com"EMAIL_PORT = 25EMAIL_HOST_USER = "huang7299@126.com"EMAIL_HOST_PASSWORD = "huang5607299" # 授權密碼EMAIL_USE_TLS = FalseEMAIL_FROM = "huang7299@126.com"===========================================2)在apps下進行目錄util,在目錄下新建文件sendmail.py============================================================import randomfrom user.models import EmailVerifyRecordfrom django.core.mail import send_mail # django內置發郵件from TFF.settings import EMAIL_FROM # 加載setting變量def randow_str(num=6):code = ''for i in range(num):r = random.randrange(0,4)if r == 0 or r == 2:m = random.randint(0,9)code += str(m)else :temp = chr(random.randint(65,90))code += str(temp)return codedef Sendmail(email,send_type=2,code_num=10):email_object = EmailVerifyRecord()code = randow_str(num=code_num)email_object.code = codeemail_object.email = emailemail_object.send_type = send_typeemail_object.save()email_title=''email_boby=''if send_type == 2 :email_title='騰飛學習網注冊激活鏈接'email_boby='請點擊下面的鏈接激活你的賬號:http://127.0.0.1:8000/active/{0}'.format(code)email_result = send_mail(email_title,email_boby,EMAIL_FROM,[email])if email_result:return Trueelse:return Falseelif send_type == 1 :email_title='騰飛學習網重置密碼鏈接'email_boby='請點擊下面的鏈接重置你的密碼:http://127.0.0.1:8000/reset/{0}'.format(code)email_result = send_mail(email_title,email_boby,EMAIL_FROM,[email])if email_result:return Trueelse:return False============================================================三、忘記密碼========================================================================= class UserReset(View):def get(self,request,code_num):email_obj = EmailVerifyRecord.objects.filter(code=code_num)for i_email in email_obj:email = i_email.emailsend_time = i_email.send_timenow_time = datetime.datetime.now()days = (now_time - send_time).daysseconds = (now_time - send_time).secondsif days == 0 and seconds < 600:user_obj = UserProfile.objects.get(email=email)return render(request,"password_reset.html",{"email_value":user_obj.email})else:continuereturn render(request,"sendmail_outtime.html")========================================================================== class UserPwdReset(View):# def get(self,request):# return render(request,'password_reset.html')def post(self,request):pwdreset_form = PwdResetForm(request.POST)email = request.POST.get('email',None)if pwdreset_form.is_valid():password1 = request.POST.get('password1',None)password2 = request.POST.get('password2',None)if password1 == password2:user_obj = UserProfile.objects.get(email=email)user_obj.password = make_password(password1)user_obj.save()return render(request,'login.html',{})else:return render(request,'password_reset.html',{"email_value":email,"mesg":u"密碼不一致"})else:return render(request,'password_reset.html',{"pwdreset_form":pwdreset_form,"email_value":email})注:重置密碼頁面不用寫get,避免直接訪問 ==========================================================================url(r'^forgetpwd/',user_views.UserForgetPWD.as_view(),name="userforgetpwd"),url(r'^reset/(?P<code_num>.*)/$',user_views.UserReset.as_view(),name="userreset"),url(r'^password_reset/',user_views.UserPwdReset.as_view(),name="pwdreset"), 注:第三條url的目的# 為了在html上form提交上使用action="{% url 'pwdreset' %}" ==========================================================================四、退出登錄 ========================================================================== class UserLogout(IsLoginRequired,View):def get(self,request):logout(request)from django.core.urlresolvers import reversereturn HttpResponseRedirect(reverse("index"))注:要用“return HttpResponseRedirect(reverse("index"))”而不用“return render(request,"index.html",{})”原因是:第一種:除了跳轉到頁面,還會執行“頁面對應view方法”,而render不會執行view方法 ============================================================================
四、前端和后臺邏輯實現數據交互
一、前端通過http方式提交數據到后臺(get,post)1、html子form表單下面要加上以下的模板語言,才能把數據提交到后臺{% csrf_token %}2、view后臺獲取數據(注:POST是大寫)if request.method == 'POST': # request包含了請求所發給后端的所有信息(請求頭,請求方式,數據。。)u_user = request.POST.get('name',None)u_email = request.POST.get('email',None)u_adress = request.POST.get('address',None)u_textinfo = request.POST.get('message',None)models.Userinfo2.objects.create(user=u_user,email=u_email,adress=u_adress,textinfo=u_textinfo)二、后臺傳遞數據到前端1、views格式: return render(request,html,{})例子:return render(request,"upbook.html",{"messgeinfo":session # session可以是字典形式 })2、html(模板語言)<div style="color: red;">{{ messgeinfo.error }}</div> # 字典獲取元素的方法messgeinfo.error 1、將上傳的圖片或者文件,展示到前端1)配置settings# 上傳文件的路徑MEDIA_URL = '/media/'MEDIA_ROOT = os.path.join(BASE_DIR,"media")2)url配置==================================================================舊版本:from django.views.static import serve # 前端顯示出圖片內容,舊版本from TFF.settings import MEDIA_ROOT# url(r'^madia/(?P<path>.*)$', serve,{"document_root":MEDIA_ROOT}), # 舊版本==================================================================# 新版本from django.conf.urls.static import static from TFF import settingsurlpatterns = []+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) # 在url配置的尾部加3)html展示{{ MEDIA_URL }}{{ obj.image }} # obj.image 為用戶上傳到數據庫的字段鳴謝:
浪子斌網址:https://www.cnblogs.com/langzibin/p/7693457.html
轉載于:https://www.cnblogs.com/songhuasheng/p/10079435.html
總結
- 上一篇: 微星X470主板装机
- 下一篇: 神舟计算机主板bios,最详细的各种主板