title: Django項目學習
date: 2017-12-13 19:32:03
tags: [網頁,Django]
category: [編程學習,網頁製做]
---css
本文主要來自於mooc公開課Django課程html
pip install virtualenv
,而後使用virtualenv 虛擬環境名
創建一個虛擬環境,在windows下面的激活方法是前端
cd django_virtual cd Script activate
在linux下只須要將最後一步換位source activatepython
在PyCharm創建程序時,直接選擇Django程序,選擇解釋器爲virtualenv創建的django環境,便可創建django項目mysql
項目創建以後,咱們獲得了以下的目錄結構,紫色的被標記爲了templet目錄,這樣就能智能提示,若是你想要在import的時候不須要加入絕對路徑,那麼就能夠mark as source root
linux
接下來咱們先嚐試運行該項目,點擊run,運行這個Django項目,能夠看到運行在了本機的8000端口,點擊該地址便可訪問:git
若是要配置監聽全部ip,那麼咱們須要經過run-Edit configurations
,將監聽端口改成0.0.0.0github
安裝好Navicat以後,打開軟件,創建鏈接,以後創建表,設計表的字段,設計完以後按ctrl+s
保存,以後就能夠插入數據條目,這就是簡單的使用方法,具體使用會在以後用到的時候詳細介紹。下載地址請點擊web
首先看看以前提到的創建django以後的目錄結構,windows使用tree \F .
獲得以下結構,linux中使用apt-get install tree
,而後tree .便可獲得
:sql
├mooc_web │ manage.py ├─mooc_web │ │ settings.py │ │ urls.py │ │ wsgi.py │ │ __init__.py └─templates
經過pycharm當中的tools-run manage.py task
,此時能夠在shell中執行Django命令:
startapp message
此時就有了一個名爲message的文件夾,將其拖入apps文件夾,自動生成了一個__init__.py
文件,這樣就讓apps變成一個能夠導入的包,爲了方便導入,那麼咱們須要將apps文件夾remark成source root,這樣每次引用的時候就不須要import apps.message.view 而是能夠直接 import message.view
這樣在pycharm中引用變得方便了,可是在使用命令行運行的時候就會出錯,此時咱們須要在settings.py中將apps加入到根搜索路徑(BASE_DIR)中
├── apps │ ├── __init__.py │ └── message │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── db.sqlite3 ├── log ├── manage.py ├── media ├── mooc_web │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── static └── templates
創建log文件夾用於存放日誌,media用於存放用戶的上傳文件,創建static存放靜態css和js文件
當app比較多的時候,就創建一個apps文件夾,將新創建的app拖進去
將html模板放入template文件夾,在static文件夾中創建css文件夾,並放入style.css文件
由於Django默認用的是sqlite數據庫,咱們要改爲mysql數據庫,打開項目的settings.py,找到DATABASES,將其中的:
django.db.backends.mysql
testDjango
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'testDjango', 'USER': 'root', 'PASSWORD': 'root', 'HOST': '127.0.0.1' } }
經過tools-Run manage.py Task
來鏈接數據庫,首先須要安裝mysqlclient,用pip install mysqlclient
安裝:
> makemigrations # 用於生成一個基於你對模型改變的遷移,在這裏就是數據庫類型從sqlite遷移到mysql > migrate # 用於應用改變
此時Django自動生成了一大堆數據庫表,在Navicat中能夠看到表的名稱:
此時能夠點擊run運行整個系統,能夠在127.0.0.1:8000上訪問該網址
可是此時的style.css沒法被找到,咱們要在settings.py中配置一下static文件夾的地址,由於STATICFILES_DIRS
可能不止一個,因此用list的形式進行賦值,其中BASE_DIR是項目文件的根目錄:
STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static') ]
在urls.py中添加新的頁面,頁面的處理函數要在apps-message-views.py
中新增,首先咱們在view.py
中構造以下函數,直接return render的模板,其中request參數是Django的請求,每一個views函數都得有:
def getform(request): return render(request, template_name='course-comment.html')
總體來講,先設置數據庫和STATICFILES_DIRS,以後這一塊再也不動,主要就是views.py寫後端邏輯,urls.py寫頁面地址url配置
普通的數據庫調用方法,鏈接(connect),生成cursor,excute sql語句,cursor.fetchall( )
orm就是把一個表映射成一個類,好比要找出name只須要調用book.name
下面咱們開始使用orm進行設計數據庫:
找到message下面的models.py文件,在其中定義一個UserMessage類,用於存放咱們須要的數據,全部model都要繼承models.Model類:
class UserMessage(models.Model): name = models.CharField(max_length=20, verbose_name='用戶名') email = models.EmailField(verbose_name='郵箱') address = models.CharField(max_length=100, verbose_name='地址') message = models.CharField(max_length=500, verbose_name='留言信箱') class Meta: verbose_name = '用戶留言信息' verbose_name_plural = verbose_name ordering = '-id' # 排序方式爲反向的id db_table = 'my_table' #設置table的名字
其中每個字段都定義一個類型,經常使用的有CharField,EmailField,DateTimeField, IntergerField, ForeignKey, IPAddressField, FileField, ImageField
其中max_length表示最大長度,verbose_name表示別名.
本身定義的model還有一個內部類Meta,用於存放全部不是Field的字段,好比排序的順序,數據表的名稱等等
點擊Tools-Run manage.py
,執行命令,發現找不到message這個model,全部咱們要去settings.py中INSTALLED_APPS
加入'app.message'
再次執行
> makemigrations message > migragate message
先引入model對象,from apps.message.models import UserMessage
,,利用model對象的objects方法,對數據進行操做
all_message = UserMessage.objects.all() #這個是能夠循環的 for message in all_messages: print(message.name) filterd_data = UserMessage.objects.filter(name='jeffrey',address='beijing') #filter方法能夠對數據進行過濾,中間的逗號表示多個條件,這裏是取出的name爲jeffrey,address爲北京的值 for message in filterd_data: print(message.name)
這裏的all就是取出全部值,filter就是取出特定條件的值
定義一個新的對象,並對其各個field賦值
user_message = UserMessage() user_message.name = 'a' user_message.message = 'a@a.com' user_message.message = 'aaaaa' user_message.save()
這樣每次訪問form頁面的時候均可以存入一條記錄
在html文件中須要進行以下更改:
<form action="/form/" method="post" class="smart-green"> 在action中填入網頁地址
須要加入CSRF安全機制,
還能夠經過頁面的表單提交增長新的數據,request的POST屬性中,以字典的形式存儲了表單中提交的值,能夠用python的get方法獲取這些值,get的第二個參數爲獲取不到時候的默認值:
if request.method == 'POST': name = request.POST.get('name','') email = request.POST.get('email', '') message = request.POST.get('message', '') user_message = UserMessage() user_message.name = 'a' user_message.email = 'a@a.com' user_message.message = 'aaaaa' user_message.save()
直接先查找到對象,而後用delete方法就能夠刪除對象
all_message = UserMessage.objects.fileter(name='bob') all_message.delete()
在view.py中,咱們能夠先取出數據,而後在render的時候,把須要傳入的參數以一個dict的形式,傳遞給context,這樣咱們就能夠在html文件中進行調用
def getform(request): message = None all_message = UserMessage.objects.filter(name='boobytest') if all_message: message = all_message[0] return render(request, template_name='course-comment.html',context={'message':message,})
在HTML文件中調用參數的方法是兩個大括號,input就輸入在value裏面,textarea就輸入在兩個標籤之間:
<input id="email" type="email" value={ { message.email } } name="email" placeholder="請輸入郵箱地址"/> <textarea id="message" name="message" placeholder="請輸入你的建議">{ { message.message } }</textarea>
在HTML文件中,使用python邏輯的方法是大括號加百分號,{ % python expression % }
if和end if成對出現
<input id="name" type="text" value="{% if not message.name == 'boobytest' %} boobyhastest{% else %}booby no test {% endif %}" name="name" class="error" placeholder="請輸入您的姓名"/>
好比在HTML中使用if和else的方法如上,固然if a==b 也可使用 ifequal a b代替,取前五位也可使用message.name|split:'5'
{% ifequal a b%} {% endif %}#用於表示等於
Django提供了不少內置的方法,具體能夠查看Django template built-in tags
url在配置過程當中可能會改變,所以咱們須要爲url設置一個不變的名字供HTML調用
在url.py中:
url(r'^form/$', getform,name='form')
在comment.html中:
<form action="{% url 'form' %}" method="post" class="smart-green">
注意,在url配置中必定要加上/$
表示以/
結尾,否則再進行正則匹配的時候可能會匹配到別的網頁
必須在url前面加上^
,後面加上/$
,這樣不會匹配出錯
mkvirtualenv mooc cd mooc/Script activate pip install Django mysqlclient
經過pycharm創建Django項目,名字爲MxOnline,首先在settings.py中更改數據庫引擎
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mxonline', 'USER': 'root', 'PASSWORD': 'root', 'HOST': '127.0.0.1', } }
經過Tools-run manage.py task
來生成數據庫的表
makemigrations migragate
首先startapp users
,在models當中,新建一個UserProfile
,繼承django.contrib.auth.models.AbstractUser
,加入你須要的自定義字段,並定義好meta信息中的verbose_name
from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class UserProfile(AbstractUser): nick_name = models.CharField(max_length=50,verbose_name='暱稱',default='') birthday = models.DateField(verbose_name='生日',null=True,blank=True) gender = models.CharField(max_length=5,choices=(('male','男'),('female','女')),default='') address = models.CharField(max_length=100,default='') mobile = models.CharField(max_length=11, null=True, blank=True) image = models.ImageField(upload_to='image/%Y/%m',default='image/default.png') class Meta: verbose_name = '用戶信息' verbose_name_plural = verbose_name
而後run manage.py,經過makemigrations users
和migragate users
生成新的user表,可能會報錯,報錯時只須要將以前生成的全部表刪除後從新生成便可
避免交叉引用,否則會出錯,使用上層app引用下層app
class EmailVerifyRecord(models.Model): code = models.CharField(max_length=20, verbose_name='驗證碼') email = models.EmailField(max_length=50, verbose_name= '郵箱') send_type = models.CharField(choices=(('register','註冊'),('forget','找回密碼')),max_length=10) send_time = models.DateTimeField(default=datetime.now) #記得去掉datetime.now的括號,否則只會記錄class生成的時間 class Meta: verbose_name = '郵箱驗證碼' verbose_name_plural = verbose_name class Banner(models.Model): title = models.CharField(max_length=100, verbose_name='標題') image = models.ImageField(upload_to='banner/%Y/%m', verbose_name='輪播圖') url = models.URLField(max_length=500, verbose_name='訪問地址') index = models.IntegerField(default=100, verbose_name='順序') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加時間') class Meta: verbose_name = '輪播圖' verbose_name_plural = verbose_name
Course -- 課程基本信息 Lesson -- 章節信息 Video -- 視頻 CourseResource -- 課程資源
一共有上述四張表
from django.db import models from datetime import datetime # Create your models here. class Course(models.Model): name = models.CharField(max_length=50, verbose_name='課程名稱') desc = models.CharField(max_length=300, verbose_name='課程描述') detail = models.TextField(verbose_name='課程詳情') degree = models.CharField(choices=(('cj','初級'),('zj','中級'),('gj','高級')),verbose_name='課程難度',max_length=2) learn_time = models.IntegerField(default=0, verbose_name='學習時長(分鐘數)') students = models.IntegerField(default=0, verbose_name='學習人數') fav = models.IntegerField(default=0, verbose_name='收藏人數') image = models.ImageField(upload_to='courses/%Y/%m', verbose_name='封面圖', max_length=100) click_num = models.IntegerField(default=0, verbose_name='點擊數') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加時間') class Meta: verbose_name='課程' verbose_name_plural = verbose_name class Lesson(models.Model): course = models.ForeignKey(Course, verbose_name='課程') name = models.CharField(max_length=100, verbose_name='章節名') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加時間') class Meta: verbose_name = '章節' verbose_name_plural = verbose_name class Video(models.Model): lesson = models.ForeignKey(Lesson, verbose_name='章節') name = models.CharField(max_length=100, verbose_name='視頻名') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加時間') class Meta: verbose_name = '視頻' verbose_name_plural = verbose_name class CourseResource(models.Model): course = models.ForeignKey(Course, verbose_name='課程') download = models.FileField(upload_to='courses/resource/%Y/%m',max_length=100) name = models.CharField(max_length=100, verbose_name='資源名稱') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加時間') class Meta: verbose_name = '課程資源' verbose_name_plural = verbose_name
CourseOrg -- 課程機構基本信息 Teacher -- 教師基本信息 CityDict -- 城市信息
添加以下
from django.db import models from datetime import datetime # Create your models here. class CourseOrg(models.Model): city = models.ForeignKey(CityDict,verbose_name='所在城市') name = models.CharField(max_length=50,verbose_name='機構名稱') desc = models.TextField(verbose_name='機構描述') click_nums = models.IntegerField(default=0, verbose_name='點擊數') fav_nums = models.IntegerField(default=0, verbose_name='收藏數') image = models.ImageField(upload_to='org/%Y/%m',verbose_name='封面圖') address = models.CharField(max_length=150,verbose_name='地址') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '課程機構' verbose_name_plural = verbose_name class CityDict(models.Model): name = models.CharField(max_length=20,verbose_name='城市') desc = models.CharField(max_length=200, verbose_name='描述') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '城市' verbose_name_plural = verbose_name class Teacher(models.Model): org = models.ForeignKey(CourseOrg, verbose_name='所屬機構') name = models.CharField(max_length=20,verbose_name='教師名') work_years = models.IntegerField(default=0, verbose_name='工做年限') work_company = models.CharField(max_length=50,verbose_name='就任公司') work_position = models.CharField(max_length=50,verbose_name='公司職位') points = models.CharField(max_length=50, verbose_name='教學特色') click_nums = models.IntegerField(default=0, verbose_name='點擊數') fav_nums = models.IntegerField(default=0, verbose_name='收藏數') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '教師' verbose_name_plural = verbose_name
UserAsk -- 用戶諮詢 CourseComments -- 用戶評論 UserFavorite -- 用戶收藏 UserMessage -- 用戶消息 UserCourse -- 用戶學習的課程
添加以下:
from django.db import models from datetime import datetime from users.models import UserProfile from courses.models import Course from organization.models import CourseOrg # Create your models here. class UserAsk(models.Model): name = models.CharField(max_length=20,verbose_name='姓名') mobile = models.CharField(max_length=11, verbose_name='手機') course_name = models.CharField(max_length=50,verbose_name='課程名稱') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '用戶諮詢' verbose_name_plural = verbose_name class CourseComments(models.Model): user = models.ForeignKey(UserProfile, verbose_name='用戶') course = models.ForeignKey(Course, verbose_name='課程') comments = models.CharField(max_length=500,verbose_name='評論') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '課程評論' verbose_name_plural = verbose_name class UserFavorite(models.Model): user = models.ForeignKey(UserProfile, verbose_name='用戶') fav_id = models.IntegerField(default=0, verbose_name='數據id') fav_type = models.IntegerField(choices=((1,'課程'),(2,'課程機構'),(3,'講師')),default=1,verbose_name='收藏類型') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '用戶收藏' verbose_name_plural = verbose_name class UserMessage(models.Model): user = models.IntegerField(default=0,verbose_name='接收用戶')# 不用外鍵,由於有多是發給全部人的消息,用0表示發送給全部人的消息,用int表示用戶的id message = models.CharField(max_length=500, verbose_name='消息內容') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') has_read = models.BooleanField(default=False,verbose_name='是否已讀') class Meta: verbose_name = '用戶消息' verbose_name_plural = verbose_name class UserCourse(models.Model): user = models.ForeignKey(UserProfile, verbose_name='用戶') course = models.ForeignKey(Course, verbose_name='課程') add_time = models.DateTimeField(datetime.now, verbose_name='添加時間') class Meta: verbose_name = '用戶課程' verbose_name_plural = verbose_name
創建new python package, 把全部的app放到apps這個包下面,注意選擇不改相對引用,並mark apps爲source root
將apps這個文件夾加入到settings當中
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(BASE_DIR,'apps'))
直接在run manage.py task中輸入createsuperuser
,輸入用戶名,郵箱和密碼就能夠登陸
更改語言和時區:
LANGUAGE_CODE = 'zh-hans' #將語言改成中文 TIME_ZONE = 'Asia/Shanghai' #將時區改成上海 USE_TZ = False # 系統使用本地時間而不是utc時間
由於咱們更改了admin的auth.user的model,所以須要註冊user的model,在users
庫中的admin.py文件中註冊:
from users.models import UserProfile # Register your models here. class UserProfileAdmin(admin.ModelAdmin): #userprofile的管理器 pass admin.site.register(UserProfile,UserProfileAdmin) #admin和model的關聯註冊
登陸http://127.0.0.1:8000/admin
就能夠對用戶進行修改
ctrl+shift+f
使用xadmin,由於我安裝的Django 2.0.1版本,因此須要安裝專門的xadmin for Django2.0
pip install git+git://github.com/sshwsfc/xadmin.git@django2
在url.py中引入xadmin
import xadmin urlpatterns = [url(r'^xadmin/', xadmin.site.urls),]
在settings.py中註冊xadmin和crispy_forms:
INSTALLED_APPS = [ 'django.contrib.admin', ....... 'xadmin', 'crispy_forms', ]
接下來同步xadmin的表:
> makemigrations > migragate
再打開http://127.0.0.1:8000/xadmin就能夠訪問xadmin的後臺管理了
在管理用戶信息的時候,會出現錯誤,這是因爲咱們用的Django是2.0.1版本,而教程中用到的是1.0+,根據pycharm報錯的最後一條,打開widget.py文件,在74行修改以下
input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != ''] if (len(input_html) > 1): input_html[0] = input_html[0] + "/>" input_html[1] = "<" + input_html[1]
在mxonline下創建一個python package文件夾extra_apps,下載xadmin並解壓,拷貝其中的xadmin文件夾到其中,並把extra_apps mark as source root,這樣引入xadmin的時候就會從相對文件引入
同時在settings.py中把xadmin文件夾加入根搜索路徑
註冊方法相似於admin的註冊方式,只不過不是在admin.py中註冊,而是要新建adminx.py,而且admin繼承的是object
import xadmin from users.models import EmailVerifyRecord class EmailVerifyRecordAdmin(object): pass xadmin.site.register(EmailVerifyRecord, EmailVerifyRecordAdmin) # 註冊方法
修改顯示的郵件驗證碼存儲記錄的str名稱:
class EmailVerifyRecord(models.Model): code = models.CharField(max_length=20, verbose_name='驗證碼') email = models.EmailField(max_length=50, verbose_name= '郵箱') ....... def __str__(self): return '{0}({1})'.format(self.code,self.email)
class Model名+Admin
在其中加入list_display(顯示列), search_fields(搜索域), list_filter(過濾器)
class LessonAdmin(object): list_display = ['course','name','add_time'] search_fields = ['course','name','add_time'] list_filter = ['course','name','add_time']
若是要使用外鍵進行搜索,能夠用兩個下劃線表示
class LessonAdmin(object): list_filter = ['course__name','name','add_time']
將全站的配置放在user app的admix.py中,新建一個class BaseSetting,用於配置主題
from xadmin import views class BaseSettings: enable_themes = True #容許使用主題 use_bootswatch = True #容許多主題 xadmin.site.register(views.BaseAdminView,BaseSettings)
創建一個class GlobalSettings配置標題名稱和footer名稱
class GlobalSettings: site_title = '慕學後臺管理系統' site_footer = '慕學在線網' menu_style = 'accordion' #摺疊model xadmin.site.register(views.CommAdminView,GlobalSettings)
在每一個model文件夾中的apps.py文件中加入verbose_name
from django.apps import AppConfig class CoursesConfig(AppConfig): name = 'courses' verbose_name = '課程'
而後在__init__.py
中加入default_app_config
default_app_config = 'courses.apps.CoursesConfig'
首先將前端給的Index.html(首頁)文件和login.html(登陸頁)文件放入templates文件夾中
在根目錄下創建static文件夾,存放css,images,js,media文件,並在settings.py中聲明STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]
,注意:這裏的STATICFILES_DIRS必須設置爲list或者tuple形式,不然會報錯
此時,將html文件中的全部css,js的文件路徑修改成/static/css
和/static/js
接下來配置url,在url.py中引入TemplateView
from django.views.generic import TemplateView urlpatterns = [ url(r'^xadmin/', xadmin.site.urls), url(r'^$',TemplateView.as_view(template_name='index.html'),name='index'), url(r'^login/', TemplateView.as_view(template_name='login.html'), name='login') ]
這樣就完成了頁面配置,重啓項目後就能夠訪問首頁和登陸頁面
如今users模塊中新建CustomBackend類,繼承ModelBackend,重寫其中的authenticate函數,用Q函數實現或操做
from django.contrib.auth.backends import ModelBackend from django.db.models import Q class CustomBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): try: user = UserProfile.objects.get(Q(username=username)|Q(email=username)) if user.check_password(password): return user except Exception as e: return None
寫本身的login函數login,並將其寫到urls.py中
views.py
def my_login(request): if request.method == 'POST': user_name = request.POST.get('username','') pass_word = request.POST.get('password','') user = authenticate(username=user_name,password=pass_word) if user: login(request, user) return render(request, 'index.html',{'userprofile':user}) else: return render(request,'login.html',{'msg':'用戶名或密碼錯誤'}) elif request.method == 'GET': return render(request, 'login.html', {})
urls.py
url(r'^login/', my_login, name='login')
在settings.py中加入AUTHENTICATION_BACKENDS=('users.views.CustomBackend',)
,將認證後臺改成本身寫的後臺
在點擊登錄後,咱們須要跳轉回首頁或者是報告密碼錯誤,此時request被傳遞到網頁中,能夠在跳轉後顯示本身的用戶名
<dd>{{ request.POST.username }}<img class="down fr" src="/static/images/top_down.png"/></dd>
views.py中加入本身的類:
from django.views.generic import View class LoginView(View): def get(self, request): return render(request, 'login.html', {}) def post(self, request): user_name = request.POST.get('username','') pass_word = request.POST.get('password','') user = authenticate(username=user_name,password=pass_word) if user: login(request, user) return render(request, 'index.html',{'userprofile':user}) else: return render(request,'login.html',{'msg':'用戶名或密碼錯誤'})
在urls.py中將loginview註冊:
url(r'^login/', LoginView.as_view(), name='login')
在users模塊彙總創建forms.py用於檢驗表單
forms.py
from django import forms class LoginForm(forms.Form): username = forms.CharField(required=True) password = forms.CharField(required=True, min_length=5)
在views.py中加入loginform的驗證,邏輯是若是有效,則提取表單中的username和password,驗證成功後,用login函數登陸,返回index頁面;若是驗證失敗,返回登陸頁顯示用戶或密碼錯誤;若是檢測到form有錯誤,返回登陸頁,顯示錯誤類型
class LoginView(View): def get(self, request): return render(request, 'login.html', {}) def post(self, request): login_form = LoginForm(request.POST) #實例化一個login_form,傳入參數爲request.POST,自動驗證其中的username和password,注意這裏名字必須和login.html的form當中的name相同 if login_form.is_valid(): #這一步以後能夠看到login_form的error類型,存爲一個dict類型 user_name = request.POST.get('username','') pass_word = request.POST.get('password','') user = authenticate(username=user_name,password=pass_word) if user: login(request, user) return render(request, 'index.html',{'userprofile':user}) else: return render(request,'login.html',{'msg':'用戶名或密碼錯誤'}) else: return render(request,'login.html',{'login_form':login_form})
在login.html中顯示錯誤類型:
<div class="error btns login-form-tips" id="jsLoginTips">{% for key, error in login_form.errors.items %} {{ error }}{% endfor %}{{ msg }}</div>
http自己是一種無狀態協議,每次發送請求,服務器返回請求的數據,若是要記住登陸狀態就須要cookies
django的cookie由session_key和session_data以及expire_data組成,實現是經過setings.py中的'django.contrib.sessions',
每一個域名之下的cookies是不能互相訪問的
先拷貝register.html到template中,配置url,
url(r'^register/',RegisterView.as_view,name='register'),
而後在views.py
中加入RegisterView類
class RegisterView(View): def get(self, request): return render(request, 'register.html')
在HTML代碼中修改指向
<a style="color:white" class="fr registerbtn" href="{% url 'register' %}">註冊</a> <a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登陸</a>
修改其css和js文件的地址,這裏介紹第二種修改的方法
首先在html文件中輸入{%load staticfiles%}
而後在須要修改地址的地方輸入{%static '/css/reset.css'%}
pip install django-simple-captcha
urlpatterns += [ url(r'^captcha/', include('captcha.urls')), ]
而後在forms.py中加入一個新的register_form,在其中加入captchafiled
from django import forms from captcha.fields import CaptchaField class RegisterForm(forms.Form): email = forms.EmailField(required=True,error_messages={'invalid':'請輸入一個有效的郵箱地址'}) password = forms.CharField(required=True,min_length=5,error_messages={'invalid':'密碼至少6個字符','required':'請輸入密碼'}) captcha = CaptchaField(error_messages={'required': '驗證碼錯誤'})
在view.py
中加入registerview
class RegisterView(View): #get方法,先實例化一個RegisterForm,將register_form返回到html中用於獲取驗證碼 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', '') pass_word = request.POST.get('password', '') is_used = UserProfile.objects.filter(username=user_name) if not is_used: user = UserProfile() user.username = user_name user.email = user_name user.password = make_password(pass_word) user.save() send_register_email(user_name) return render(request, 'login.html',{}) else: return render(request, 'register.html', {'msg':'該用戶名已經被佔用','register_form':register_form}) else: return render(request, 'register.html',{'register_form':register_form})
修改register.html
<div class="tab-form"> <!--其中的action用於指定提交到哪一個頁面--> <form id="email_register_form" method="post" action="{% url 'register' %}" autocomplete="off"> <input type='hidden' name='csrfmiddlewaretoken' value='gTZljXgnpvxn0fKZ1XkWrM1PrCGSjiCZ'/> <!--在class裏面加入{%if register_form.email.errors %}errorput用於出錯時高亮--> <div class="form-group marb20 {% if register_form.email.errors %}errorput{% endif %}"> <label>郵 箱</label> <!--將value填爲上次填寫的value,這樣出錯時不用用戶每次手動填寫value--> <input type="text" id="id_email" name="email" value="{{ register_form.email.value }}" placeholder="請輸入您的郵箱地址"/> </div> <div class="form-group marb8 {% if register_form.errors.password %}errorput{% endif %}"> <label>密 碼</label> <input type="password" id="id_password" name="password" value="{{ register_form.password.value }}" placeholder="請輸入6-20位非中文字符密碼"/> </div> <div class="form-group marb8 captcha1 {% if register_form.errors.password %}errorput{% endif %}"> <label>驗 證 碼</label> {{ register_form.captcha }} </div> <div class="error btns" id="jsEmailTips"> <!--用循環的方式將錯誤顯示出來--> {% for key,value in register_form.errors.items %} {{ value }} {% endfor %} {{ msg }} </div> <div class="auto-box marb8"> </div> <input class="btn btn-green" id="jsEmailRegBtn" type="submit" value="註冊並登陸"/> {# <input type='hidden' name='csrfmiddlewaretoken' value='5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy'/>#} {% csrf_token %} </form> </div>