前言
之前我们用Django框架做了一个很简单的个人博客搭建,不论是页面还是功能都很粗糙
所以从这篇开始我打算做一个比较完整的【个人博客网站】,可能会分好几篇博客来讲述
等所有功能完善的差不多后,再考虑上传github
- 那本篇呢,我们主要实现博客的基础框架搭建,以及【登陆/注册/注销】功能的实现 我会顺便详细介绍一下小知识点,以及我踩的坑
- 简易版blog搭建:https://blog.csdn.net/Makasa/article/details/124982130?spm=1001.2014.3001.5502
环境:
- Pycharm
- python3.6
- mysql 5.7
- django 2.0.13
一、整体框架介绍
1、创建Django项目
- 直接在pycharm里新建一个Django项目即可

2、框架简要介绍

3、项目概览



二、准备工作
1、创建blog数据库
- 数据库我这里用的是mysql5.7


2、将静态资源移入项目
- 在应用同级目录下,创建static文件夹;且将静态资源复制在其下 静态资源下载地址:https://www.ip3q.com/free/1243.html

三、MyBlog模块具体实现
1、setting全局配置

importosfrompathlibimportPath#Buildpathsinsidetheprojectlikethis:BASE_DIR/'subdir'.BASE_DIR=Path(__file__).resolve().parent.parent#Quick-startdevelopmentsettings-unsuitableforproduction#Seehttps://docs.djangoproject.com/en/3.1/howto/deployment/checklist/#SECURITYWARNING:keepthesecretkeyusedinproductionsecret!SECRET_KEY='hf&ss)e1pr49yngt1s9ql%7wgotm91vsvw&88$67@3p@hlm%^e'#SECURITYWARNING:don'trunwithdebugturnedoninproduction!DEBUG=TrueALLOWED_HOSTS=[]#ApplicationdefinitionINSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',#自己的应用'user.apps.UserConfig',]MIDDLEWARE=['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',]ROOT_URLCONF='MyBlog.urls'#如果用户继承了AbstractUser,修改原生auth_user的模型的话就需要加这个配置AUTH_USER_MODEL='user.UserProfile'TEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates','DIRS':[os.path.join(BASE_DIR,'templates')],'APP_DIRS':True,'OPTIONS':{'context_processors':['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',#如果要在页面里面进行引用图片的话,就必须在这里添加配置'django.template.context_processors.media'#在模板中可以使用{{MEDIA_URL}}],},},]WSGI_APPLICATION='MyBlog.wsgi.application'#Database#https://docs.djangoproject.com/en/3.1/ref/settings/#databasesDATABASES={'default':{'ENGINE':'django.db.backends.mysql','NAME':'blog','USER':'root','PASSWORD':'yy1998123','HOST':'127.0.0.1','PORT':'3306',}}#Passwordvalidation#https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS=[{'NAME':'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME':'django.contrib.auth.password_validation.MinimumLengthValidator',},{'NAME':'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME':'django.contrib.auth.password_validation.NumericPasswordValidator',},]#Internationalization#https://docs.djangoproject.com/en/3.1/topics/i18n/#配置语言,时区LANGUAGE_CODE='zh-hans'TIME_ZONE='Asia/Shanghai'USE_I18N=TrueUSE_L10N=TrueUSE_TZ=False#Staticfiles(CSS,JavaScript,Images)#https://docs.djangoproject.com/en/3.1/howto/static-files/STATIC_URL='/static/'#配置静态文件夹路径STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]#配置媒体文件路径MEDIA_URL=''MEDIA_ROOT=os.path.join(BASE_DIR,'media')
2、urls.py

fromdjango.contribimportadminfromdjango.urlsimportpath,includefromuser.viewsimportindex"""全局路径"""urlpatterns=[path('admin/',admin.site.urls),path('',index,name='index'),#配置user路径path('user/',include(('user.urls','user'),namespace='user')),#path('user/',include('user.urls',namespace='user')),]
四、user模块具体实现
1、在user文件下新建urls.py
- 简单提及下:我们这里为什么要再单独在user应用下创建一个urls.py呢?主要是为了让代码更加规范,一般情况下,项目比较大的话,我们肯定是有多个应用的,那各个应用的路径我们就统一配置在全局的urls中单个应用底下的路由我们都配在一起,方便统一管理;比如说:咱们这次做的登录注册功能,是与用户相关的,那我们就单独在user应用下新建一个urls.py,里面配置用户相关的操作,例:登录/注册/注销等…


"""用户相关的路径"""fromdjango.urlsimportpathfromuser.viewsimportuser_register,user_login,user_logouturlpatterns=[path('register',user_register,name='register'),path('login',user_login,name='login'),path('logout',user_logout,name='logout'),]
2、views.py
- 这里【用户注销】的操作我写了两种方法,大家详细可以看下注释,我写得比较清楚
- 另外这里踩了个坑,找问题找了很久:启动项目后,页面表单显示不出来****原因:判断 request.method = ‘GET’ 时,这个get一定要用全部大写,用‘Get’不行

fromdjango.contrib.authimportlogoutfromdjango.contrib.auth.hashersimportmake_password,check_passwordfromdjango.db.modelsimportQfromdjango.httpimportHttpResponsefromdjango.shortcutsimportrender,redirect#Createyourviewshere.fromdjango.urlsimportreversefromuser.formsimportRegisterForm,LoginFormfromuser.modelsimportUserProfile"""视图函数"""defindex(request):"""返回首页:paramrequest::return:"""returnrender(request,"index.html")defuser_register(request):"""用户注册:paramrequest::return:"""ifrequest.method=='GET':#注意get一定要大写,不然无法将表单渲染在页面上returnrender(request,'user/register.html')else:rform=RegisterForm(request.POST)#使用form获取数据print('--------》',rform)print("errors",rform.errors)ifrform.is_valid():#进行数据的校验#从干净的数据中取值,即通过前端校验的数据username=rform.cleaned_data.get('username')email=rform.cleaned_data.get('email')mobile=rform.cleaned_data.get('mobile')password=rform.cleaned_data.get('password')#如果用户名/手机号不存在的话,才进行添加数据操作ifnotUserProfile.objects.filter(Q(username=username)|Q(mobile=mobile)).exists():#注册到数据库中password=make_password(password)#密码进行加密user=UserProfile.objects.create(username=username,password=password,email=email,mobile=mobile)ifuser:#如果用户创建成功,则提示注册成功returnHttpResponse('注册成功')else:#否则用户名/手机号已存在returnrender(request,'user/register.html',context={'msg':'用户名或者手机号已经存在!'})#数据校验失败,就提示注册失败returnrender(request,'user/register.html',context={'msg':'用户名或者手机号已经存在,请重新填写!'})defuser_login(request):"""用户登陆:paramrequest::return:"""ifrequest.method=='GET':returnrender(request,'user/login.html')else:lform=LoginForm(request.POST)print('--------》',lform)print("errors",lform.errors)iflform.is_valid():username=lform.cleaned_data.get('username')password=lform.cleaned_data.get('password')#查询数据库,如果加密后的两个密码一致的话登录成功user=UserProfile.objects.filter(username=username).first()flag=check_password(password,user.password)ifflag:#登陆成功后,保存session信息,并进入首页#session信息会保存到django_session表中,并进行base64加密request.session['username']=usernamereturnredirect(reverse('index'))returnrender(request,'user/login.html',context={'errors':lform.errors})defuser_logout(request):"""用户注销:paramrequest::return:"""#方法一、可自行清空session,再重定向到首页#request.session.clear()#仅删除字典#用户注销后,把session给清空,并且重定向回首页#request.session.flush()#删除django_session+cookie+字典#returnredirect(reverse('index'))#方法二、若model类继承了AbstractUser,可直接使用系统自带的退出登录,即logout;不需要自己去清空sessionlogout(request)returnredirect(reverse('index'))
3、models.py

fromdjango.contrib.auth.modelsimportAbstractUserfromdjango.dbimportmodels#Createyourmodelshere."""数据库模型类"""#继承AbstractUser,可以使用他本身的登录/退出登录方法;#同时也可以继承auth_user本身的所有数据库字段classUserProfile(AbstractUser):#这里我们设置mobile为唯一,之后方便用于登录校验mobile=models.CharField(max_length=11,verbose_name="手机号",unique=True)#icon的图片我们指定生成到media文件夹里,并且记得去settings里面进行配置#media创建在static同级目录下#upload_to表示文件上传的路径,uploads/%Y/%m/%d:他会在media文件底下依次创建2019--05--文件名icon=models.ImageField(upload_to='uploads/%Y/%m/%d')classMeta:db_table='userprofile'verbose_name='用户表'verbose_name_plural=verbose_name
4、forms.py
- 在user应用下新建forms.py,为了进行表单校验这里的表单校验我写了两种方法,详细可看代码注释- 方法一、继承Form- 方法二、继承ModelForm

importrefromdjangoimportformsfromdjango.core.exceptionsimportValidationErrorfromdjango.formsimportFormfromdjango.forms.modelsimportModelFormfromuser.modelsimportUserProfile#写法一、继承From的写法#classUserRegisterForm(Form):#username=forms.CharField(max_length=50,min_length=6,error_messages={'min_lengh':"用户名至少6位"},label="用户名")#email=forms.EmailField(required=True,error_messages={'required':"必须填写邮箱信息"},label='邮箱')#mobile=forms.CharField(required=True,error_messages={'required':"必须填写手机号"},label='手机号')##widget=forms.widgets.PasswordInput输入框为密码格式#password=forms.CharField(required=True,error_messages={'required':"必须填写密码"},label='密码',#widget=forms.widgets.PasswordInput)##defclean_username(self):#username=self.cleaned_data.get('username')##username正则匹配#result=re.match(r'[a-zA-Z]\w{5,}',username)#ifnotresult:#raiseValidationError('用户名必须字母开头')#returnusername#写法二、这里是继承modelForm的写法,继承modelForm可以获取到model里面所有的值classRegisterForm(ModelForm):"""注册表单"""classMeta:#获取到模型里面的属性model=UserProfile#fields='__all__’即获取所有属性#exclude=['username','email']即排除这些字段fields=['username','email','mobile','password']defclean_username(self):username=self.cleaned_data.get('username')#username正则匹配result=re.match(r'[a-zA-Z]\w{5,}',username)ifnotresult:raiseValidationError('用户名必须字母开头')returnusernameclassLoginForm(Form):"""登录表单"""username=forms.CharField(max_length=50,min_length=6,error_messages={'min_lengh':"用户名至少6位"},label="用户名")password=forms.CharField(required=True,error_messages={'required':"必须填写密码"},label='密码',widget=forms.widgets.PasswordInput)defclean_username(self):#拿到表单里面的用户名username=self.cleaned_data.get('username')#校验数据库里面这个用户名是否存在,不存在就抛出异常ifnotUserProfile.objects.filter(username=username).exists():raiseValidationError('用户名不存在')returnusername
五、templates模块具体实现
1、首先创建base.html
- 为什么要创建base.html? base页面主要是从原静态页面index.html提取出来的公用代码,为了提高代码的复用性,其他页面之后直接继承该页面即可

{%loadstaticfiles%}<htmllang="en"><head><metacharset="UTF-8"><title>{%blocktitle%}Mikasa个人博客{%endblock%}</title><metaname="keywords"content="个人博客,Mikasa个人博客,个人博客模板,Mikasa"/><metaname="description"content="Mikasa个人博客"/><linkhref="{% static 'css/base.css' %}"rel="stylesheet"><linkhref="{% static 'css/index.css' %}"rel="stylesheet"><!--[ifltIE9]><scriptsrc="{% static 'js/modernizr.js' %}"></script><![endif]--><scriptsrc="{% static 'js/scrollReveal.js' %}"></script>{#如果要使用jquery的话,记得把jquery引用加上,可以直接去百度一下搜索一个版本直接复制粘贴#}<scriptsrc="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>{%blockmycss%}{%endblock%}</head><body><header><br><br><divstyle="text-align: right">{#如果session里面有值的话就显示:欢迎!用户名,如果没有值的话就显示:登录/注册#}{%ifrequest.session.username%}欢迎!<ahref="#">{{request.session.username}}</a> <ahref="{% url 'user:logout' %}">注销登录</a>{%else%}<ahref="{% url 'user:login' %}">登录</a> <ahref="{% url 'user:register' %}">注册</a>{%endif%}</div><divclass="logo"data-scroll-reveal="enter right over 1s"><ahref="/"><imgsrc="{% static 'images/logo2.png' %}"></a></div><navclass="topnav"data-scroll-reveal="enter bottom over 1s after 1s"><ahref="{% url 'index' %}"><span>首页</span><spanclass="en">Home</span></a><ahref="about.html"><span>关于我</span><spanclass="en">About</span></a><ahref="manshenghuo.html"><span>慢生活</span><spanclass="en">Life</span></a><ahref="learn.html"><span>碎言碎语</span><spanclass="en">Doing</span></a><ahref="learn.html"><span>学无止境</span><spanclass="en">Learn</span></a><ahref="gbook.html"><span>留言</span><spanclass="en">Saying</span></a></nav></header><article><divclass="container">{%blockcontent%}{%endblock%}</div></article><footer>DesignbyDanceSmile<ahref="/">粤ICP备11002373号-1</a></footer><script>if(!(/msie[6|7|8|9]/i.test(navigator.userAgent))){(function(){window.scrollReveal=newscrollReveal({reset:true});})();};</script>{#js#}{%blockmyjs%}{%endblock%}</body></html>
2、创建index.html
- 该页面为首页,目前很多东西都是写死的,之后我们再优化

{%extends'base.html'%}{%loadstaticfiles%}{%blockcontent%}<divclass="blog"data-scroll-reveal="enter top"><figure><ul><ahref="/"><imgsrc="{% static 'images/t01.jpg' %}"><span>下载个人博客模板</span></a></ul><p><ahref="/">灯具公司复古风格PSD设计稿</a></p><figcaption>此模板为PSD设计稿,复古风格。首页主要突出产品,以及公司简介。手绘灯作为头部背景图片,这个比较特别。html可以做出灯一闪一闪的效果,或者说旁边有个按钮...</figcaption></figure><figure><ul><ahref="/"><imgsrc="{% static 'images/t02.jpg' %}"><span>下载个人博客模板</span></a></ul><p><ahref="/">个人博客模板古典系列之——江南墨..</a></p><figcaption>一共是四个页面,首页,图文列表,图片列表,文字内容。此模板风格为中国古典风格,山水画墨迹成就一幅江南墨卷。页面首页设计较为简单,突出文章重点。图文列表显示...</figcaption></figure><figure><ul><ahref="/"><imgsrc="{% static 'images/t03.jpg' %}"><span>下载个人博客模板</span></a></ul><p><ahref="/">美丽的茧</a></p><figcaption>让世界拥有它的脚步,让我保有我的茧。当溃烂已极的心灵再不想做一丝一毫的思索时,就让我静静回到我的茧内,以回忆为睡榻,以悲哀为覆被,这是我唯一的美丽。</figcaption></figure></div><ulclass="cbp_tmtimeline"><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t03.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t02.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t01.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t03.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t02.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t01.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li><li><timeclass="cbp_tmtime"><span>08-08</span><span>2017</span></time><divclass="cbp_tmicon"></div><divclass="cbp_tmlabel"data-scroll-reveal="enter right over 1s"><h2>三步实现滚动条触动css动画效果</h2><p><spanclass="blogpic"><ahref="/"><imgsrc="{% static 'images/t03.jpg' %}"></a></span>现在很多网站都有这种效果,我就整理了一下,分享出来。利用滚动条来实现动画效果,ScrollReveal.js用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力...</p><ahref="/"target="_blank"class="readmore">阅读全文>></a></div></li></ul>{%endblock%}
3、在templates下创建user文件夹
- 为了代码更规范,我们将不同功能的页面放在一个文件夹下;比如:用户相关的登陆/注册页面,统一建个user文件夹,放其下面

3.1、login.html
{%extends'base.html'%}{%loadstaticfiles%}{%blocktitle%}用户登录{%endblock%}{#css样式部分#}{%blockmycss%}<linkhref="{% static 'css/register.css' %}"rel="stylesheet"type="text/css"media="all"/><linkhref="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i" rel="stylesheet"/>{%endblock%}{#内容部分#}{%blockcontent%}<divclass="main"><divclass="main-w31"><h1class="logo-w3">个人博客用户登录</h1><divclass="w3layouts-main"><h2><span>请登录</span></h2><pstyle="color: red">{{msg}}{{errors}}</p><formaction="{% url 'user:login' %}"method="post">{%csrf_token%}<inputplaceholder="用户名"name="username"type="text"required=""><inputplaceholder="密码"name="password"type="password"id="password1"required=""><inputtype="submit"value="登录"name="login"></form></div></div></div>{%endblock%}
3.2、register.html
{%extends'base.html'%}{%loadstaticfiles%}{%blocktitle%}用户注册{%endblock%}{#css样式部分#}{%blockmycss%}<linkhref="{% static 'css/register.css' %}"rel="stylesheet"type="text/css"media="all"/><linkhref="https://fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i"rel="stylesheet"/>{%endblock%}{#内容部分#}{%blockcontent%}<divclass="main"><divclass="main-w31"><h1class="logo-w3">个人博客用户注册</h1><divclass="w3layouts-main"><h2><span>现在注册</span></h2><p>{{msg}}{{errors}}</p><formaction="{% url 'user:register' %}"method="post">{%csrf_token%}<inputplaceholder="用户名"name="username"type="text"required=""><br><inputplaceholder="邮箱"name="email"type="email"required=""><br><inputplaceholder="手机号码"name="mobile"type="text"required=""><br><inputplaceholder="密码"name="password"type="password"id="password1"required=""><br><inputplaceholder="确认密码"name="password"type="password"id="password2"required=""><br><inputtype="submit"value="提交注册"name="login"><br></form></div></div></div>{%endblock%}{#js部分#}{%blockmyjs%}<script>addEventListener("load",function(){setTimeout(hideURLbar,0);},false);functionhideURLbar(){window.scrollTo(0,1);}</script><script>{#密码校验#}window.onload=function(){document.getElementById("password1").onchange=validatePassword;document.getElementById("password2").onchange=validatePassword;}functionvalidatePassword(){varpass1=document.getElementById("password1").value;varpass2=document.getElementById("password2").value;if(pass1!=pass2)document.getElementById("password2").setCustomValidity("密码不匹配")elsedocument.getElementById("password2").setCustomValidity("")}</script>{%endblock%}
六、登录/注册界面样式代码
1、register.css
- 原静态模板下是没有登录/注册界面的,所以样式也需要自己调,放css下即可

@charset"UTF-8";/*初始化所有默认样式*/ol,ul{list-style:none;margin:0;padding:0;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}table{border-collapse:collapse;border-spacing:0;}/*starteditingfromhere*/a{text-decoration:none;}.txt-rt{text-align:right;}/*textalignright*/.txt-lt{text-align:left;}/*textalignleft*/.txt-center{text-align:center;}/*textaligncenter*/.float-rt{float:right;}/*floatright*/.float-lt{float:left;}/*floatleft*/.clear{clear:both;}/*clearfloat*/.pos-relative{position:relative;}/*PositionRelative*/.pos-absolute{position:absolute;}/*PositionAbsolute*/.vertical-base{vertical-align:baseline;}/*verticalalignbaseline*/.vertical-top{vertical-align:top;}/*verticalaligntop*//*.underline{*//*padding-bottom:5px;*//*border-bottom:1pxsolid#eee;*//*margin:0020px0;*//*}*//*Add5pxbottompaddingandaunderline*/nav.verticalulli{display:block;}/*verticalmenu*/nav.horizontalulli{display:inline-block;}/*horizontalmenu*/img{max-width:100%;}/*endreset*/bodya{transition:0.5sall;-webkit-transition:0.5sall;-o-transition:0.5sall;-moz-transition:0.5sall;-ms-transition:0.5sall;}ul{padding:0;margin:0;}h1,h2,h3,h4,h5,h6{margin:0;padding:0;}p{padding:0px;margin:10px;color:#ff4444;font-size:18px;}/*main*/.main{text-align:center;}h1.logo-w3{font-size:3em;text-transform:uppercase;letter-spacing:4px;color:#ffffff;text-align:center;margin:5%0;width:100%;}.w3layouts-mainh2{color:#fff;font-size:29px;letter-spacing:2px;text-transform:uppercase;margin-bottom:30px;text-align:center;}.w3layouts-main{max-width:420px;margin:0auto;background:rgba(0,0,0,0.2);text-align:center;-webkit-box-shadow:0px0px20px0pxrgba(0,0,0,0.75);-moz-box-shadow:0px0px20px0pxrgba(0,0,0,0.75);box-shadow:0px0px20px0pxrgba(0,0,0,0.75);}.w3layouts-main{padding:40px30px;}input[type="text"],input[type="email"],input[type="password"]{width:100%;padding:15px;outline:none;font-size:15px;font-weight:100;color:#FFFFFF;margin-bottom:20px;font-family:'Montserrat',sans-serif;border:1pxsolid#fff;background:transparent;background:rgba(0,0,0,0.2);letter-spacing:1px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;box-sizing:border-box;}input[type="submit"]{width:100%;padding:14px30px;font-size:14px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;text-transform:uppercase;letter-spacing:1px;background:#fff;color:#333;border:none;outline:none;cursor:pointer;font-family:'Montserrat',sans-serif;transition:0.5sall;-webkit-transition:0.5sall;-o-transition:0.5sall;-moz-transition:0.5sall;-ms-transition:0.5sall;}input[type="submit"]:hover{background:#ff4f81;color:#fff;transition:0.5sall;-webkit-transition:0.5sall;-o-transition:0.5sall;-moz-transition:0.5sall;-ms-transition:0.5sall;}.w3layouts-main2input[type="submit"]{margin:27pxauto31px;}/*placeholder-color*/::-webkit-input-placeholder{color:#fff;}:-moz-placeholder{color:#FFFFFF;}::-moz-placeholder{color:#FFFFFF;}:-ms-input-placeholder{color:#FFFFFF;}/*footer*/.footer-w31p{margin:3.5em0em0em;color:#FFFFFF;font-size:15px;font-weight:300;letter-spacing:2px;line-height:26px;}.footer-w31a{color:#100e0e;font-family:'Montserrat',sans-serif;}.footer-w31a:hover{color:#FFFFFF;text-decoration:underline;}/*responsive*/@media(max-width:1600px){h1.logo-w3{margin:1em0;}}@media(max-width:1440px){h1.logo-w3{font-size:2.8em;}}@media(max-width:1366px){h1.logo-w3{font-size:2.7em;}.footer-w31p{margin:3em0em2em;}}@media(max-width:1280px){h1.logo-w3{font-size:2.8em;}.footer-w31p{margin:4.5em0em0em;}}@media(max-width:1080px){h1.logo-w3{font-size:2.7em;letter-spacing:3px;}.footer-w31p{margin:4.5em0em0em;}}
七、创建数据库表及启动项目
1、创建数据库表
- 正常情况下是直接创建成功,我这里遇到了问题,详细可以看下后面
pythonmanage.pymakemigrationspythonmanage.pymigrate


1.1)在这儿是遇到了问题:ModuleNotFoundError: No module named ‘MySQLdb’

解决方法
import pymysql
pymysql.install_as_MySQLdb()

2、访问项目

本文转载自: https://blog.csdn.net/Makasa/article/details/125028122
版权归原作者 M1kasal 所有, 如有侵权,请联系我们删除。
版权归原作者 M1kasal 所有, 如有侵权,请联系我们删除。