首先做一个自我介绍,我是一个开发小白,目前只是一个学生,之前从来没有开发过这种比较完整的系统,这给系统算是我的处女做吧。现在的我不过是个学生,里面一些东西都是自学搞定,其实仔细处理的话,也并不是很难,以下的内容,是我整个开发这个博客系统的心路历程以及经验分享,还请各位大佬们能够多多指点。
http://zj.sdwu-top.top/ 这个是我的成品,大家可以注册感受一下......
第一步,在做一个东西的时候,我觉得首要的就是分析,去了解我们真正需要的是什么。我要做的是一个博客,更直接的就是一个网站。做网站需要的是(仅发表自己的分析):需要前端的设计和后台数据的处理,进一步讲,我们需要的是:
- django网站制作框架,语言是Python
- 数据库(这里我们用的是sqlite3——>这个是我装载完django之后默认的轻量数据库)
- 前端:Html5 CSS JS,这里前端推荐一个框架Bootstrap4,效果很不错
- 服务器选择:作为一个学生,阿里云有一种轻量应用服务器,大家可以在里面找一找,价格很美好,适合学生党。
- 编辑器选择:推荐文本编辑器 notepad++。 https://notepad-plus-plus.org/ 官网下载即可,非常方便,当然如果大家有更好的编辑器也可以推荐哟~
第二步,环境配置(前提安装Python3环境)
-
安装django 命令行输入
pip install django
- 创建第一个Django工程
django-admin.py startproject zhuce
|
|
|
这个位置是你建的工程名字(自己配置)
- 进入工程文件夹,创建第一个app
django-admin.py startapp register
|
|
|
这个位置是你建的app的的名字(自己取)
那么,我们这样创建的究竟是什么呢?我们一起来了解一下结构首先:
zhuce #(project_name)
├── manage.py
├── zhuce
| ├── __init__.py
| ├── settings.py
| ├── urls.py
| └── wsgi.py
└──register #(app_name)
├─── __init__.py
├─── __pycache__
├─── migrations 这里存放的是数据库修改的日志数据
├─── models.py
├─── admin.py
├─── views.py
├─── apps.py
└─── tests.py
里面的各个文件究竟是什么呢?在此,只介绍我用到的
settings.py
我的理解是Dajngo内部设置,及环境的配置,比如引入的app文件,DEBUG开关,静态文件位置等等
models.py
数据库操作文件
admin.py
功能比较强大的后台管理
urls.py
网址入口,关联到对应的views.py中的一个函数,访问网址就对应一个函数。
views.py
处理用户请求,从urls.py中对应过来, 通过渲染templates中的网页可以显示内容
为了方便,在此提前介绍一下模板文件夹templates以及静态文件存放文件夹static
templates文件夹
我的理解是我们写的网页模板存放的地方,需要手动创建,位置和app文件夹同级
static文件夹
django有他独特的静态文件处理方法,图片之类的,和templates文件夹一样,都需要手动创建,位置和app文件夹同级
读到这,我们对django这个框架已经是基本了解了,开始动手创建
第三步:settings.py配置
首先把我们创建的app添加到里面
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'register', #在这个位置添加上你创建的app名字
]
为了之后的方便,在此先将templates和static配置好
templates:
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',
],
},
},
]
static:
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,"static")
]
第四步:设计数据库models.py ————>这一步很重要
在我们做任何工程之前,如果要用到数据库,在做之前一定要设计好数据库,本人曾在数据库上面吃过亏,没设计好,就开始做了,结果后续过程中每次都要改,很麻烦......
这是我部分数据库内容,里面涉及到一的叫做tinymce的,这个是django自带的富文本编辑app
from django.db import models
from tinymce.models import HTMLField
# Create your models here.
class register(models.Model):
username = models.CharField(u'姓名',max_length=30,primary_key=True)
password = models.CharField(u'密码',max_length=16)
select_admin = models.BooleanField(default=False)
def _str_(self): #_str_ 将一个类的实例返回str类型的方法
return self.username
class Article(models.Model):
articleID = models.AutoField(u'文章号',primary_key=True)
articleTitle = models.CharField(u'文章标题',max_length=26)
articleContent = HTMLField(u'文章内容')
articleAutor = models.CharField(u'作者',max_length=16)
articleTime = models.DateField(u'时间',auto_now_add=True)
def _str_ (self):
return self.articleID
在models.py里面写完之后并不是就这么完了
命令行运行
python manage.py makemigrations
python manage.py migrate
如果不主动提示创建管理,运行:
python manage.py createsuperuser
第五步,规划后台admin.py
from django.contrib import admin
from .models import *
class registerAdmin(admin.ModelAdmin):
list_display = ('username','password','select_admin')
#list_display 在这个地方是列取显示我们数据库里面的列名(不用全部显示,列出几个显示几个)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('articleID','articleTitle','articleContent','articleTime')
admin.site.register(register,registerAdmin)
admin.site.register(Article,ArticleAdmin)
第六步:配置url(和views.py对应,如果没有特别注意的,下文就暂且不提了)
from django.contrib import admin
from django.conf.urls import url,include
from register import views
urlpatterns = [
url(r'^admin/', admin.site.urls), #还有path('admin/', admin.site.urls)写法,path是2.0以上写法,当然两种写法现在兼容,以后每一个界面以及功能都需要urls
......
]
第七步 编写需求views.py
此时,我们需要不同的需求
首页index
首页其实很简单,我们返回这个网页就好,url配置的话直接到首页
def index(request):
return render(request,'index.html')
url(r'^$', views.index),
登录login
本来是不想设置登录的,因为毕竟是开源的博客,但是,这本身算是我个人意义上的处女作,我觉得全面一些
比较好,所以设置了一个登录系统,当然,这样对我们的管理会更加清晰,现在虽然必须要登录才能看,但之
后会做一些优化,设置一个一个游客,这是后话了。
首先,做一个登录的话,我们需要知道两个方法:GET POST
GET 和 POST 都是一种HTTP请求的方式
在django中都是request里面的方法,是获取参数的两个重要的方法。
def login(request): #登录验证
if request.method=="POST":
username=request.POST.get('username')
password=request.POST.get('password')
user=register.objects.filter(username=username,password=password)
print(user)
if user:
request.session['is_login']='1'
request.session['user_id']=user[0].username
return redirect('/blog/')
return render(request,'login.html')
先解析一下这个吧,用的是POST方法,获取到我们的数据库里面的username和password
那么,哪一句是获取数据库的值这个呢,有一个方法是register.objects.filter(),这是获取的register表里
面的字段内容,其中(username=username,password=password)是一个判断我们输入的和我们数据
库内部的内容是否相同,然后如果是user,成功登陆之后,有一个方法:session
在此不再过多介绍,我博客里面有提到
表单的话不多提,因为每个人的表单都不一样
但在我们写完之后,可能会遇到crsf报错的问题,这是因为表单提交请求的问题,在此也不多说
只要在我们的表单内部开头处添加上{% csrf_token %}即可
注册register
1:数据库(register)----->数据库在上篇登录上已经建好了,其中有个细节我觉得大家都应该能察觉
到,那就是我将username设置成了主键。其实很好理解:假如,我们不设置主键的话,那么在我们注册的
时候,数据库中的数据假如我们注册了一个相同的账号,数据库也将不会做出任何反应。
当然,需要给大家一个忠告:在我们做一个系统的时候,需要用到数据库时,我们一定要好好设计一下数据
库。因为小编曾经因为数据库问题折腾了很长一段时间,就是因为当初没有设计好,逻辑上有问题。
2.HTTP请求,POST GET
》》》这个在之前登录上面已经写到了,这个不再多说
3.对于相同账号的处理,当我们注册成功或者失败的时候,数据库本身是能显示的,但是为了增加用户的体
验,我们需要在前端设定用户是否注册成功。
4.需要了解到表单------->forms.py
当然,对于一些简单的,可以直接在views.py里面写的
我理解的是这是一个暂时存放数据的表单,对数据的暂时存储
说到这里,有几个关于表单操作的方法大家有必要了解一下,因为我们需要用到
cleaned_data 就是读取表单返回的值,返回类型是字典dict型
is_valid() 是对于表单的判断,如果正确返回True,如果错误返回flase
def regist(request): #注册验证
try:
if request.method =="POST":
register_form = UserForm(request.POST)
if register_form.is_valid():
username=register_form.cleaned_data['username']
password=register_form.cleaned_data['password']
try:
register.objects.create(username=username,password=password)
return render(request,'share1.html')
except:
return render(request,'share1.html',{'username':username})
else:
register_form=UserForm()
return render(request,'register.html',{'register_form':register_form})
except:
return render(request,'register.html',{'register_form':register_form})
简单说一下这一串代码的逻辑:
先是用了POST 的方法,去获取字典内的数据,当然,把上面建的表单引用,表单的请求也需要用POST,
用is_valid()判断内部是否正确
register.objects.create这个方法是在register数据库上创建字段
返回的时候有个取值传参{‘register_form’:register_form}
解释一下,首先第一个‘register_form’,是对这个参数的取名,目的是为了在前端html上取值引用,第二
个register_form是之前的那个获取的参数register_form = UserForm(request.POST),是之前写到的
这个参数内部的值。,也就是说,我之前的第一个‘register_form’,可以起一些方便我们书写的名字。
表单的话
<div class="container">
<form class="form-horizontal" role="form" action="/regist/" method="post">
{% csrf_token %}
<div class="form-group" id="box">
<label for="firstname" class="col-sm-2 control-label"><strong>username</strong></label>
<div class="col-sm-12">
<input type="text" class="form-control" name="username" placeholder="请输入名字" id="txt_content" required="true" minlength="6">
</div>
</div>
<div class="form-group" id="box">
<label for="lastname" class="col-sm-2 control-label"><strong>password<strong></label>
<div class="col-sm-12">
<input type="password" class="form-control" name="password" placeholder="请输入密码" id="txt_content" required="true" minlength="6">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10" style="text-align:center">
<p><button class="btn btn-success" id="btn"'><strong>确  定</strong></button>
</p>
</div>
</div>
</form>
</div>
这是我的表单,具体界面什么样大家可以天马行空,重点不要忘记method以及action
这里说一下captcha验证码吧,这是一给django自带的验证码app
为什么要添加这个验证码呢,如果不能添加一个验证,我们的数据库容易被攻击,换句话说,对于产品的安全性存在风险,添加验证,会减少很大一部分的安全风险
在此先把方法简单一提
1.pip install django-simple-captcha
2.在setting里面添加captcha
INSTALLED_APPS = [
.......,
'register',
'tinymce',
'captcha'
]
3.配置urls.py
from django.contrib import admin
from django.conf.urls import url,include
from register import views
urlpatterns = [
...... ,
url(r'^captcha/',include('captcha.urls')),
]
4.表单创建
from django import forms
from captcha.fields import CaptchaField #这是引用的是captcha自带的验证码输入框
class UserForm(forms.Form): #注册表单
username = forms.CharField(label='用户名',max_length=100)
password = forms.CharField(label='密_码',widget=forms.PasswordInput())
captcha = CaptchaField(error_messages={'invalid': '验证码错误'})
5.注册验证
def regist(request): #注册验证
try:
if request.method =="POST":
register_form = UserForm(request.POST)
if register_form.is_valid():
username=register_form.cleaned_data['username']
password=register_form.cleaned_data['password']
try:
register.objects.create(username=username,password=password)
return render(request,'share1.html')
except:
return render(request,'share1.html',{'username':username})
else:
register_form=UserForm()
return render(request,'register.html',{'register_form':register_form})
except:
return render(request,'register.html',{'register_form':register_form})
在前端中添加
{{ register_form.captcha }}#这是关键,直接调用验证码,其内部是自动生成
博客列表blog和博客内容detail
def blog(request): #博客列表
user_id1=request.session.get('user_id')
userobj=register.objects.filter(username=user_id1).get()
blogs = Article.objects.all().order_by('-articleTime')
print(userobj.select_admin)
return render(request,'blog.html',{"user":userobj,'blogs':blogs})
def get_details(request,blog_id): #文章内容
user_id1=request.session.get('user_id')
user = register.objects.filter(username=user_id1).get()
try:
blog=Article.objects.get(articleID=blog_id)
except Article.DoesNotExist:
raise Http404
return render(request,'blogcontent.html',{"blog":blog,"user":user})
前端界面:
{% for article in blogs %}
<div class="container-fluid">
<div class="title">
<a href="{% url 'blog_get_detail' article.articleID %}"><h2>{{article.articleTitle}}</h2></a>
</div>
<div class = "info">
<span class="articleAutor" style="margin:center">{{article.articleAutor}}</span>  
<span class ="articleTime">{{article.articleTime}}</span>
</div>
</div>
{% endfor %}
这个地方有必要说一下,因为当时的我对{%xxx%} 以及{xxx.yyyyy}这种东西不理解,从而导致之后一
些步骤就走的很慢
我们上述的比如{{article.articleAutor}}这个的话,{{ }}---->这是取值的符号,然后article 这个其
实我上次在注册的那篇文章中也提到过,这是我们在views.py 里面的取值,这个例子稍微转了一个弯,但
不妨碍。先看这句:blog = Article.objects.all().order_by('-articleTime')
这句话是获取了Article数据库里面的所有列的所有值,按照我设置的时间顺序(逆序),值是存储到blog
里面,之后另一句话return render(request,'blogcontent.html',{"blog":blog,"user":user})注意
后面这个加粗的位置,前面文章提到过,这个是将获取到的blog取了一个blog的名字传到html里面,这两
部其实就是传参,{% %}这是一个django中的模板语法,在这里用的是for循环来遍历我们的blog取值,
将取的值都改名为article,所以才有了我们{{article.articleAutor}}的article,而articleAutor就很好理
解了,这是我们数据库里面的列名,也就是说,这句话的意思就是获取到我们article数据库里面的
articleAutor列中的内容
{% for article in blogs %} ------->循环开头
......
{% endfor %} ------>循环结尾
{% url 'blog_get_detail' article.articleID %}那么,为什么要加这一步呢,这是因为其内部室友选择
的, 'blog_get_detail'这个地方大家可以注意到urls里
面url(r'^detail/(\d+)/$',views.get_details,name='blog_get_detail'),一种取名方式,方便我们传
值。
这里的话总结一下,其中显示博客内容的重点就是传参,从值的获取和传参
私人管理submit
本来是不打算的做这个的,这个需要选择管理员,只是用来方便我自己的,具体先不做介绍,这里主要说一下Django自带的富文本框
tinymce
富文本编辑器是什么?
根据我个人的见解(当然只是自己的理解,官方专业的说法如有雷同,不胜荣幸)来说,我觉得就是一个嵌入到html的文本编辑器。当然这种编辑器的功能比较强大,包括对文本以及不同文件的处理等等,非常方便使用者编辑。
设置settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'register',#自己本身建的的app
'tinymce'#这个是我们下的django的插件,这里需要加上‘tinymce’
然后添加编辑配置选项
TINYMCE_DEFAULT_CONFIG = {
'theme': 'advanced',
'width': 600,
'height': 400,
}
前端上添加
<script src="/static/tiny_mce/tiny_mce.js"></script>
<script>
tinyMCE.init({
'mode':'textareas',
'theme':'advanced',
'width':600,
'height':400
})
</script>
<form>
<label>
<textarea name="comment_content"></textarea>
</label>
<br>
<input type="submit" value="发布" class="btn btn-primary btn-lg">
</form>
之后,想看效果的话,首先,可以在本地上看,找到工程文件
命令行输入
python manage.py runserver
最终:
在服务器上运行:
python manage.py runserver 0.0.0.0:80
然后访问域名或者IP
以上就是我做这个博客的分享经验,希望能得到大家的指导交流.....