学习Python的日子 博客项目

博客项目
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、文章分页
10、文章详情页功能
11、文章添加点赞功能
12、文章评论功能
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'))
14、删除文章功能
15、一个多对多的案例
例子:一个作者对应多本书,一本书有多个作者
model代码:
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.从书籍出发获取作者
b = Book.objects.get(id=50)  
b.authors.all()  
b.authors.filter(first_name='Adam')  
2.从作者出发获取书籍
a = Author.objects.get(id=1)  
a.book_set.all()  
(二)添加对象方法:
a = Author.objects.get(id=1)  
b = Book.objects.get(id=50)  
b.authors.add(a)  
(三)删除对象对象方法:
a = Author.objects.get(id=1)  
b = Book.objects.get(id=50)  
b.authors.remove(a) 或者 b.authors.filter(id=1).delete() 

猜你喜欢

转载自blog.csdn.net/qq_42240071/article/details/80670850
今日推荐