简单博客开发流程
blog开发流程
1、分析页面
分析页面达到的目的
1):完成网站的模块划分
2):从模板页面当中抽象出父模板,实现模板页面继承
3):分析模块当中的数据模型,确定模型类当中的字段
2、用户模块
扩展已经存在的模型
1)、onetoone扩展
2)、使用内部auth继承构建自己的用户表
第一步:创建模型类继承于内部user表的可继承类
from django.db import models
from django.contrib.auth.models import AbstractUser,User
from datetime import datetime
# Create your models here.
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=20,verbose_name="用户昵称",null=True,blank=True)
url = models.URLField(max_length=100,verbose_name="用户主页",null=True,blank=True)
add_time = models.DateTimeField(default=datetime.now,verbose_name="添加时间")
def __str__(self):
return self.username
class Meta:
verbose_name = '用户信息'
verbose_name_plural = verbose_name
第二步:需要在settings当中指定默认的用户表为我们自己创建的这个表
AUTH_USER_MODEL = 'users.UserProfile'
3、django forms验证
forms 一般有两个作用,(1)它可以直接返回一个form表单,(2)它可以对我们页面上的form表单字段进行验证,只要模板页面上有form表单,那么它在我们的后台肯定对应了一个form类去做验证。
在我们的app当中新建一个python文件,名字叫做forms,以后只要是写的form验证类,我们统一写在这个文件当中。先在forms文件当中写好我们的form表单验证的类,例如,登陆注册各自都有自己对应的form表单验证类,以及验证规则。
from django import forms
class UserRegisterForm(forms.Form):
username = forms.CharField(max_length=20,min_length=6,required=True)
email = forms.EmailField(max_length=100,min_length=8)
url = forms.URLField(max_length=100,min_length=8)
password = forms.CharField(max_length=20,min_length=8,required=True)
password1 = forms.CharField(max_length=20,min_length=8,required=True)
class UserLoginForm(forms.Form):
username = forms.CharField(max_length=20,min_length=6,required=True)
password = forms.CharField(max_length=20,min_length=8,required=True)
在view视图当中我们就可以通过实例化我们的form类,对我们用户提交的数据进行验证。
form类实例化及验证
def user_register(request):
if request.method == 'GET':
return render(request,'reg.html')
else:
#实例化form类,用来验证用户提交的数据
user_register_form = UserRegisterForm(request.POST)
#一个判断方法:判断这个form验证是否通过(合法),如果合法返回True,不合法返回False
if user_register_form.is_valid():
#如果验证合法,那么会把合法的干净的数据存储在form对象的一个属性cleaned_data
#当中,这个属性是一个字典,我们可以这样去拿干净的数据
username = user_register_form.cleaned_data['username']
email = user_register_form.cleaned_data['email']
url = user_register_form.cleaned_data['url']
password = user_register_form.cleaned_data['password']
password1 = user_register_form.cleaned_data['password1']
user = UserProfile.objects.filter(username=username)
if user:
return render(request,'reg.html',{
'msg':'帐号已经存在'
})
else:
if password == password1:
a = UserProfile()
a.username =username
a.email = email
a.url = url
a.password = password
a.set_password(password)
a.save()
return redirect(reverse('users:user_login'))
else:
return render(request, 'reg.html', {
'msg': '密码不一致'
})
else:
return render(request, 'reg.html', {
'user_register_form': user_register_form
})
def user_login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
user_login_form = UserLoginForm(request.POST)
if user_login_form.is_valid():
username = user_login_form.cleaned_data['username']
password = user_login_form.cleaned_data['password']
user = authenticate(username = username,password = password)
if user:
login(request,user)
return redirect(reverse('index'))
else:
return render(request,'login.html',{
'msg':'用户名或者密码错误'
})
else:
return render(request, 'login.html', {
'user_login_form': user_login_form
})
显示错误消息
表单如果验证失败,那么会有一些错误消息,这些消息会存储在form对象当中的一个errors属性当中,这个属性也是一个字典,我们可以通过遍历这个字典,拿到我们想要的错误消息
<div>
{{ msg }}
{% for key,err in user_login_form.errors.items %}
{{ err }}
{% endfor %}
</div>
错误消息自定义
4、完成用户模块登陆注册和退出功能
如何设置统一管理所有的应用
5、显示首页文章信息
5.1图片媒体文件的配置
1)、在settings配置媒体文件夹的访问路径
#配置媒体文件夹
MEDIA_URL = '/static/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'static/media')
2)、在settings中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',
'django.template.context_processors.media',
],
},
},
]
3)、在主路由中配置媒体文件渲染视图处理函数
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^users/', include('users.urls',namespace='users')),
url(r'^articles/', include('articles.urls', namespace='articles')),
url(r'^$',index,name='index'),
url(r'^static/media/(?P<path>.*)',serve,{'document_root':MEDIA_ROOT})
]
在模板中,图片的显示使用软连接
<img src="{{ MEDIA_URL }}{{ article.image }}" width="700px" height="300px">
6、完成排行榜
7、完成标签云
8、完成文章归档
9、文章分页
Paginator对象
- Paginator(列表,int):返回分页对象,参数为列表数据,每面数据的条数
属性
- count:对象总数
- num_pages:页面总数
- page_range:页码列表,从1开始,例如[1, 2, 3, 4]
方法
- page(num):下标以1开始,如果提供的页码不存在,抛出InvalidPage异常
异常exception
- InvalidPage:当向page()传入一个无效的页码时抛出
- PageNotAnInteger:当向page()传入一个不是整数的值时抛出
- EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出
Page对象
创建对象
- Paginator对象的page()方法返回Page对象,不需要手动构造
属性
- object_list:当前页上所有对象的列表
- number:当前页的序号,从1开始
- paginator:当前page对象相关的Paginator对象
方法
- has_next():如果有下一页返回True
- has_previous():如果有上一页返回True
- has_other_pages():如果有上一页或下一页返回True
- next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
- previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
- len():返回当前页面对象的个数
- 迭代页面对象:访问当前页面中的每个对象
10、文章详情页功能
11、文章添加评论
12、文章点赞
Ajax
13、添加文章功能
上传图片
def article_add(request):
if request.method == "GET":
all_category = Category.objects.all()
return render(request,'article_add.html',{
'all_category':all_category
})
else:
arttitle = request.POST.get('arttitle','')
artdesc = request.POST.get('artdesc','')
artimage = request.FILES.get('artimage','')
artcategory = request.POST.get('artcategory','')
arttag = request.POST.get('arttag','')
artcontent = request.POST.get('artcontent','')
cat = Category.objects.filter(name=artcategory)[0]
art = ArticleInfo()
art.title = arttitle
art.desc = artdesc
art.image = 'article/'+artimage.name
art.content = artcontent
art.category_id = cat.id
art.author_id = request.user.id
art.save()
tag = TagInfo()
tag.name = arttag
tag.save()
tag.article.add(art)
file_name = os.path.join(MEDIA_ROOT,str(art.image))
with open(file_name,'wb') as f:
for c in artimage.chunks():
f.write(c)
return redirect(reverse('index'))
15、一个多对多的案例:
例子:一个作者对应多本书,一本书有多个作者
model代码:
[python] view plain copy
- class Author(models.Model):
- first_name = models.CharField(max_length=30)
- last_name = models.CharField(max_length=40)
- email = models.EmailField()
- class Book(models.Model):
- title = models.CharField(max_length=200)
- authors = models.ManyToManyField(Author)
(一)获取对象方法:
1.从书籍出发获取作者
[python] view plain copy
- b = Book.objects.get(id=50)
- b.authors.all()
- b.authors.filter(first_name='Adam')
2.从作者出发获取书籍
[python] view plain copy
- a = Author.objects.get(id=1)
- a.book_set.all()
(二)添加对象方法:
[python] view plain copy
- a = Author.objects.get(id=1)
- b = Book.objects.get(id=50)
- b.authors.add(a)
(三)删除对象对象方法:
[python] view plain copy
- a = Author.objects.get(id=1)
- b = Book.objects.get(id=50)
- b.authors.remove(a) 或者 b.authors.filter(id=1).delete()
中间件
中间件的5中方法
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_exception(self, request, exception)
process_response(self, request, response)
process_template_response(self,request,response)
- 是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出
- **:添加到Django配置文件中的MIDDLEWARE_CLASSES元组中
- 每个中间件组件是一个独立的Python类,可以定义下面方法中的一个或多个
- _init _:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件
- process_request(request):执行视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
- process_view(request, view_func, view_args, view_kwargs):调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
- process_template_response(request, response):在视图刚好执行完毕之后被调用,在每个请求上调用,返回实现了render方法的响应对象
- process_response(request, response):所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象
- process_exception(request,response,exception):当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象
- 使用中间件,可以干扰整个处理过程,每次请求中都会执行中间件的这个方法
- 示例:自定义异常处理
- 与settings.py同级目录下创建myexception.py文件,定义类MyException,实现process_exception方法
from django.http import HttpResponse
class MyException():
def process_exception(request,response, exception):
return HttpResponse(exception.message)
- 将类MyException注册到settings.py中间件中
MIDDLEWARE_CLASSES = (
'test1.myexception.MyException',
...
)
from django.shortcuts import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class SpiderMiddleWare(MiddlewareMixin):
def process_request(self,request):
http_user_agent = request.META.get('HTTP_USER_AGENT')
http_user_agent = str(http_user_agent).lower()
if "py" in http_user_agent:
return HttpResponse('滚蛋,小爬虫')
def process_response(self,request, response):
return response
推荐阅读
-
android应用开发之spinner控件的简单使用
-
Django如何开发简单的查询接口详解
-
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
-
详解如何在cmd命令窗口中搭建简单的python开发环境
-
Python的Flask开发框架简单上手笔记
-
Android系统开发中log的使用方法及简单的原理
-
HTML5移动端手机网站开发流程
-
Android开发之背景动画简单实现方法
-
迅捷流程图怎么设计一个简单组员表格?
-
EpiiAdmin 开源的php交互性管理后台框架, 让复杂的交互变得更简单!Phper快速搭建交互性平台的开发框架,基于Thinkphp5.1+Adminlte3.0+Require.js。