简单博客开发流程

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

  1. class Author(models.Model):    
  2.     first_name = models.CharField(max_length=30)    
  3.     last_name = models.CharField(max_length=40)    
  4.     email = models.EmailField()    
  5.         
  6. class Book(models.Model):    
  7.     title = models.CharField(max_length=200)    
  8.     authors = models.ManyToManyField(Author)    


(一)获取对象方法:

1.从书籍出发获取作者

[python] view plain copy

  1. b = Book.objects.get(id=50)  
  2. b.authors.all()  
  3. b.authors.filter(first_name='Adam')  

2.从作者出发获取书籍

[python] view plain copy

  1. a = Author.objects.get(id=1)  
  2. a.book_set.all()  

(二)添加对象方法:

[python] view plain copy

  1. a = Author.objects.get(id=1)  
  2. b = Book.objects.get(id=50)  
  3. b.authors.add(a)  


(三)删除对象对象方法:

[python] view plain copy

  1. a = Author.objects.get(id=1)  
  2. b = Book.objects.get(id=50)  
  3. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值