1.urls

from django.conf.urls import url
from django.contrib import admin
from blog import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^get_valid_code/', views.get_valid_code),
url(r'^register/', views.register),
url(r'^check_username/', views.check_username),
url(r'^index/', views.index),
url(r'^logout/', views.logout),
]

2.settings

"""
Django settings for BBS project. Generated by 'django-admin startproject' using Django 1.11.25. For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'kujfnfd#)my=#u$o(kj__^$_opl^ro=&525*fmki1wpf2z6r2v' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog.apps.BlogConfig',
] 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 = 'BBS.urls' 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',
],
},
},
] WSGI_APPLICATION = 'BBS.wsgi.application' # Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bbs',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '',
}
} # Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_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/1.11/topics/i18n/ # LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
] AUTH_USER_MODEL = 'blog.UserInfo'

3.models

from django.db import models
from django.contrib.auth.models import AbstractUser # Create your models here.
# UserInfo这个表,继承AbstractUser,因为要用auth组件 class UserInfo(AbstractUser):
nid = models.AutoField(primary_key=True)
# blank=True 只是admin中表单提交的时候,做校验,如果设置成True,就是不校验了
phone = models.CharField(max_length=32, null=True, blank=True)
# upload_to需要传一个路径(文件夹自动创建)
avatar = models.FileField(upload_to='avatar/', default='/static/img/default.png/')
blog = models.OneToOneField(to='Blog', to_field='nid', null=True) class Meta:
# admin中显示表名
verbose_name = '用户信息表'
# 表名去掉s
verbose_name_plural = verbose_name class Blog(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=64)
site_name = models.CharField(max_length=32)
theme = models.CharField(max_length=64) def __str__(self):
return self.site_name class Category(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=64)
blog = models.ForeignKey(to='Blog', to_field='nid', null=True) def __str__(self):
return self.title class Tag(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=64)
blog = models.ForeignKey(to='Blog', to_field='nid', null=True) class Article(models.Model):
nid = models.AutoField(primary_key=True)
# verbose_name='文章标题 修改admin中表单的文字显示
title = models.CharField(max_length=64, verbose_name='文章标题')
desc = models.CharField(max_length=255)
# 大文本TextField()
content = models.TextField() create_time = models.DateTimeField(auto_now_add=True) # 因为查询多,写入少,所以加这三个字段,以后不需要再连表查询了
commit_num=models.IntegerField(default=0)
up_num=models.IntegerField(default=0)
down_num=models.IntegerField(default=0) blog = models.ForeignKey(to='Blog', to_field='nid', null=True)
category = models.ForeignKey(to='Category', to_field='nid', null=True)
tag = models.ManyToManyField(to='Tag', through='ArticleToTag', through_fields=('article', 'tag')) def __str__(self):
return self.title # 手动创建第三张表
class ArticleToTag(models.Model):
nid = models.AutoField(primary_key=True)
article = models.ForeignKey(to='Article', to_field='nid')
tag = models.ForeignKey(to='Tag', to_field='nid') class Commit(models.Model):
nid = models.AutoField(primary_key=True)
user = models.ForeignKey(to='UserInfo', to_field='nid')
article = models.ForeignKey(to='Article', to_field='nid')
content = models.CharField(max_length=255)
create_time = models.DateTimeField(auto_now_add=True)
# 这样写是可以的
# parent_id=models.IntegerField()
# 自关联
# parent_id=models.ForeignKey(to='Commit',to_field='nid')
parent = models.ForeignKey(to='self', to_field='nid', null=True,blank=True) class UpAndDown(models.Model):
nid = models.AutoField(primary_key=True)
user = models.ForeignKey(to='UserInfo', to_field='nid')
article = models.ForeignKey(to='Article', to_field='nid')
is_up = models.BooleanField() class Meta:
# 联合唯一,只是为了不写脏数据
unique_together = (('user', 'article'),)

4.blog/myforms.py

from django import forms
from django.forms import widgets
from blog import models
from django.core.exceptions import ValidationError class RegForm(forms.Form):
username = forms.CharField(max_length=18, min_length=2, label="用户名",
widget=widgets.TextInput(attrs={'class': 'form-control'}),
error_messages={"max_length": '字符长度超出限制', "min_length": '字符长度不够', "required": '用户名不能为空'}
)
password = forms.CharField(max_length=18, min_length=2, label="密码",
widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
error_messages={"max_length": '字符长度超出限制', "min_length": '字符长度不够', "required": '密码不能为空'}
)
re_password = forms.CharField(max_length=18, min_length=2, label="确认密码",
widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
error_messages={"max_length": '字符长度超出限制', "min_length": '字符长度不够', "required": '密码不能为空'}
)
email = forms.EmailField(label="邮箱",
widget=widgets.TextInput(attrs={'class': 'form-control'}),
error_messages={"invalid": '格式不合法', "required": '邮箱为必填'}
) # 局部校验钩子函数
def clean_username(self):
name = self.cleaned_data.get('username')
# 去数据库校验
ret = models.UserInfo.objects.filter(username=name).first()
if ret:
raise ValidationError('用户名已存在')
return name # 全局校验钩子函数
def clean(self):
pwd = self.cleaned_data.get('password')
re_pwd = self.cleaned_data.get('re_password')
if pwd and re_pwd:
if pwd == re_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致')

5.views

from django.shortcuts import render, HttpResponse,redirect
from PIL import Image, ImageDraw, ImageFont
import random
from io import BytesIO
# https://www.cnblogs.com/liuqingzheng/articles/10023849.html
from blog import myforms
from django.contrib import auth
from django.http import JsonResponse
from blog import models # Create your views here.
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
# 判断前台发送的请求是不是ajax的请求
elif request.is_ajax():
response = {'user': None, 'msg': None}
name = request.POST.get('name')
pwd = request.POST.get('pwd')
valid_code = request.POST.get('valid_code')
if valid_code.upper() == request.session.get('valid_code').upper():
user = auth.authenticate(request, username=name, password=pwd)
if user:
# ajax请求,不能再返回render页面,或者redirect,只能返回字符串
# 校验通过,一定要登录
auth.login(request, user)
response['user'] = name
response['msg'] = '登录成功'
else:
# 用户密码错误
response['msg'] = '用户名或密码错误'
else:
response['msg'] = '验证码错误'
return JsonResponse(response) def get_random_color():
return (
random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
) def get_valid_code(request):
# pillow是一个图形处理的模块
# 生成一张图片,模式,大小,颜色
# img = Image.new('RGB', (320, 35), color=get_random_color())
# # 保存到本地
# with open('valid_code.png', 'wb') as f:
# img.save(f, 'png')
# with open('valid_code.png', 'rb') as f:
# data = f.read()
# return HttpResponse(data) # 在内存中生成一个空文件(把它想象成open('valid_code.png','wb')as f:
# 一个是在硬盘上一个是在内存中
# img = Image.new('RGB', (320, 35), color=get_random_color())
# f=BytesIO()
# img.save(f,'png')
# data=f.getvalue()
# return HttpResponse(data) img = Image.new('RGB', (320, 35), color=get_random_color())
img_draw = ImageDraw.Draw(img)
font = ImageFont.truetype('static/font/ss.ttf', size=25)
random_code = ''
for i in range(5):
char_num = random.randint(0, 9)
char_lower = chr(random.randint(97, 122))
char_upper = chr(random.randint(65, 90))
char_str = str(random.choice([char_num, char_lower, char_upper]))
# 坐标,文字,颜色,字体
img_draw.text((i * 30 + 12, 0), char_str, get_random_color(), font=font)
random_code += char_str
# 把验证码保存到session 中
request.session['valid_code'] = random_code
f = BytesIO()
img.save(f, 'png')
data = f.getvalue()
return HttpResponse(data) def register(request):
if request.method == 'GET':
my_form = myforms.RegForm()
return render(request, 'register.html', {'my_form': my_form})
elif request.is_ajax():
response = {'status': 100, 'msg': None}
print(request.POST)
my_form = myforms.RegForm(request.POST)
if my_form.is_valid():
# 存数据,返回正确信息
# 得用create_user()
# 定义一个字典,把清理的数据赋给它
dic = my_form.cleaned_data
# 移除掉确认密码字段
dic.pop('re_password')
# 取出上传的文件对象
my_file = request.FILES.get('my_file')
if my_file:
# 放到字典中
dic['avatar'] = my_file
user = models.UserInfo.objects.create_user(**dic)
print(user.username)
response['url'] = '/login/'
else:
# 返回错误信息
response['status'] = 101
response['msg'] = my_form.errors
return JsonResponse(response) def check_username(request):
response = {'status': 100, 'msg': None}
name = request.POST.get('name')
user = models.UserInfo.objects.filter(username=name).first()
if user:
response['status'] = 101
response['msg'] = '用户名已被占用'
return JsonResponse(response) def index(request):
article_list=models.Article.objects.all().order_by('-create_time')
return render(request,'index.html',{'article_list':article_list}) def logout(request):
auth.logout(request)
return redirect('/index/')

6.index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script> <title>博客园</title>
<style>
.article_bottom span {
margin-right: 5px;
}
</style>
</head>
<body>
<div class="head">
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">博客园</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">文章 <span class="sr-only">(current)</span></a></li>
<li><a href="#">随笔</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if request.user.is_authenticated %}
<li><a href="#">{{ request.user.username }}</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true"
aria-expanded="false">个人中心 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">修改密码</a></li>
<li><a href="#">修改头像</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">注销</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登录</a></li>
<li><a href="/register/">注册</a></li>
{% endif %} </ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">重金求子</div>
<div class="panel-body">
请联系:8888888888888888888
</div>
</div> <div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">交友社区</h3>
</div>
<div class="panel-body">
<a href="http://www.baidu.com">请点击</a>
</div>
</div>
</div>
<div class="col-md-7">
{% for article in article_list %}
<div>
<h4><a href="">{{ article.title }}</a></h4>
<div class="media">
<div class="media-left">
<a href="#">
<img class="media-object" src="/static/img/default.png" alt="..." height="70" width="70">
</a>
</div>
<div class="media-body">
{{ article.desc }}
</div>
</div>
<div style="margin-top: 10px;" class="article_bottom">
<span><a href="">{{ article.blog.userinfo.username }}</a></span>
<span>发布于 {{ article.create_time|date:"Y-m-d H:i:s" }}</span>
{# 反向查询,一对多,按表名小写_set#}
<span class="glyphicon glyphicon-comment"><a href="">评论({{ article.commit_num}})</a></span>
<span class="glyphicon glyphicon-thumbs-up"><a href="">点赞({{ article.up_num }})</a></span>
</div>
</div>
{% endfor %} </div>
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">重金求子</div>
<div class="panel-body">
请联系:8888888888888888888
</div>
</div> <div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">交友社区</h3>
</div>
<div class="panel-body">
<a href="http://www.baidu.com">请点击</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

7.login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script> <title>博客园</title>
<style>
.article_bottom span {
margin-right: 5px;
}
</style>
</head>
<body>
<div class="head">
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">博客园</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">文章 <span class="sr-only">(current)</span></a></li>
<li><a href="#">随笔</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if request.user.is_authenticated %}
<li><a href="#">{{ request.user.username }}</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true"
aria-expanded="false">个人中心 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">修改密码</a></li>
<li><a href="#">修改头像</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">注销</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登录</a></li>
<li><a href="/register/">注册</a></li>
{% endif %} </ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">重金求子</div>
<div class="panel-body">
请联系:8888888888888888888
</div>
</div> <div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">交友社区</h3>
</div>
<div class="panel-body">
<a href="http://www.baidu.com">请点击</a>
</div>
</div>
</div>
<div class="col-md-7">
{% for article in article_list %}
<div>
<h4><a href="">{{ article.title }}</a></h4>
<div class="media">
<div class="media-left">
<a href="#">
<img class="media-object" src="/static/img/default.png" alt="..." height="70" width="70">
</a>
</div>
<div class="media-body">
{{ article.desc }}
</div>
</div>
<div style="margin-top: 10px;" class="article_bottom">
<span><a href="">{{ article.blog.userinfo.username }}</a></span>
<span>发布于 {{ article.create_time|date:"Y-m-d H:i:s" }}</span>
{# 反向查询,一对多,按表名小写_set#}
<span class="glyphicon glyphicon-comment"><a href="">评论({{ article.commit_num}})</a></span>
<span class="glyphicon glyphicon-thumbs-up"><a href="">点赞({{ article.up_num }})</a></span>
</div>
</div>
{% endfor %} </div>
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">重金求子</div>
<div class="panel-body">
请联系:8888888888888888888
</div>
</div> <div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">交友社区</h3>
</div>
<div class="panel-body">
<a href="http://www.baidu.com">请点击</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

8.register.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<script src="/static/jquery-3.3.1.js"></script>
<title>注册</title>
<style>
#my_file {
{#把上传文件的控件隐藏#} display: none;
}
</style>
{# <script>#}
{# //等文档加载完毕之后,再进行操作#}
{# window.onload=function () {#}
{# #}
{# }#}
{# </script>#}
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>注册</h1>
<form action="" id="form">
{% csrf_token %}
{% for foo in my_form %}
<div class="form-group">
<label for="{{ foo.auto_id }}">{{ foo.label }}</label>
{{ foo }} <span class="error pull-right" style="color: red;"></span>
</div>
{% endfor %}
<div class="form-group">
<label for="my_file">头像
<img src="/static/img/default.png" alt="" width="80" height="80" id="img_file">
</label> <input accept="image/*" type="file" id="my_file">
</div> <input type="button" value="注册" class="btn btn-primary" id="btn"><span class="error"></span>
</form> </div>
</div>
</div>
</body>
<script>
//这个控件指发生变化的事件
$("#my_file").change(function () {
//先取出文件(图片)
var file_obj = $("#my_file")[0].files[0];
//通过文件阅读器,把图片放到img标签上
//生成一个文件阅读器对象
var filereader = new FileReader()
//把图片对象,读到filereader对象中
filereader.readAsDataURL(file_obj)
//filereader.result 这是filereader对象的值
//把
//$("#img_file").attr('src',filereader.result)
filereader.onload = function () {
$("#img_file").attr('src', filereader.result)
} }) $("#btn").click(function () {
//因为要上传文件,生成formdata对象
var formdata = new FormData()
/*
formdata.append('name', $("#id_name").val())
formdata.append('pwd', $("#id_pwd").val())
formdata.append('re_pwd', $("#id_re_pwd").val())
formdata.append('email', $("#id_email").val())
formdata.append('email', $("#id_email").val())
formdata.append('csrfmiddlewaretoken', $("[name='csrfmiddlewaretoken']").val()) //把文件放到formdata中
formdata.append('my_file', $("#my_file")[0].files[0]) */ //$("#form").serializeArray()把form表单打包,转成对象(列表套字典)
var arr = $("#form").serializeArray()
//jquery的循环,传参数:第一个参数是要循环的对象,第二个参数是一个匿名函数
$.each(arr, function (k, v) {
console.log(k)
console.log(v)
formdata.append(v.name, v.value)
})
//把文件放到formdata中
formdata.append('my_file', $("#my_file")[0].files[0])
console.log(arr)
$.ajax({
url: '/register/',
type: 'post',
processData: false,
contentType: false,
data: formdata,
success: function (data) {
//console.log(data)
if (data.status == 100) {
//location.href='/login/'
location.href = data.url
} else {
//在之前清除
$(".form-group").removeClass('has-error')
$(".error").html("")
$.each(data.msg, function (key, value) {
console.log(key, value)
//根据key,通过id取出控件
//原来取值
//$("#id_username").next().html()
//方式一
//$("#id_"+key).next().html(value[0])
//$("#id_"+key).parent().addClass('has-error')
//方式二
//处理两次密码不一致的情况
if (key=='__all__'){
$("#id_re_password").next().html(value[0])
}
$("#id_" + key).next().html(value[0]).parent().addClass('has-error')
})
/*
setTimeout(function () {
//清除掉父div的has-error
//清除掉错误信息(span里的内容)
$(".form-group").removeClass('has-error')
$(".error").html("")
}, 3000) */
}
}
})
}) //name失去焦点,发ajax的请求校验用户是否存在
//校验,但是只要值不变,只校验一次
/*
$("#id_username").change(function () { })
*/
//一直会校验
$("#id_username").blur(function () {
$.ajax({
url: '/check_username/',
type: 'post',
//name加不加引号都可以
data: {name:$("#id_username").val(),'csrfmiddlewaretoken': '{{ csrf_token }}' },
success:function (data) {
if (data.status==101){
$("#id_username").next().html(data.msg).parent().addClass('has-error')
}
else {
$("#id_username").next().html(data.msg).parent().removeClass('has-error')
}
}
})
}) </script>
</html>

Django---博客项目实战的更多相关文章

  1. tp5博客项目实战1

    tp5博客项目实战 开发准备:环境wamp,windows系统为例.看实战博客,默认会搭建开发环境并且tp5框架已经至少有一定的基础. tp5的下载与安装 方法一:直接在官网下载拷贝到wamp你的项目 ...

  2. Django——博客项目

    博客项目 目前的目标是构建一个基于Django的前后端完整的博客系统,首先对项目流程整理如下: 1. 分析需求 1.1. 基于用户认证组件和Ajax实现登录验证 图形验证码核心代码: 模板: < ...

  3. django博客项目8:文章详情页

    首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容.现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样 ...

  4. django博客项目5:博客首页视图(2)

    真正的 Django 博客首页视图 在此之前我们已经编写了 Blog 的首页视图,并且配置了 URL 和模板,让 Django 能够正确地处理 HTTP 请求并返回合适的 HTTP 响应.不过我们仅仅 ...

  5. django博客项目3:创建 Django 博客的数据库模型

    设计博客的数据库表结构 博客最主要的功能就是展示我们写的文章,它需要从某个地方获取博客文章数据才能把文章展示出来,通常来说这个地方就是数据库.我们把写好的文章永久地保存在数据库里,当用户访问我们的博客 ...

  6. django博客项目2.建立 Django 博客应用

    建立博客应用 我们已经建立了 Django 博客的项目工程,并且成功地运行了它.不过到目前为止这一切都还只是 Django 为我们创建的项目初始内容,Django 不可能为我们初始化生成博客代码,这些 ...

  7. django博客项目1.环境搭建

    安装 Python Windows 下安装 Python 非常简单,去 Python 官方网站找到 Python 3 的下载地址,根据你的系统选择 32 位或者 64 位的安装包,下载好后双击安装即可 ...

  8. 9.28 Django博客项目(一)

    2018-9-28 17:37:18 今天把博客项目 实现了注册和添加图片的功能! 放在了自己的github上面 源码! https://github.com/TrueNewBee/bbs_demo ...

  9. django博客项目6:Django Admin 后台发布文章

    在此之前我们完成了 Django 博客首页视图的编写,我们希望首页展示发布的博客文章列表,但是它却抱怨:暂时还没有发布的文章!如它所言,我们确实还没有发布任何文章,本节我们将使用 Django 自带的 ...

  10. django博客项目4:博客首页视图(1)

    Web 应用的交互过程其实就是 HTTP 请求与响应的过程.无论是在 PC 端还是移动端,我们通常使用浏览器来上网,上网流程大致来说是这样的: 我们打开浏览器,在地址栏输入想访问的网址,比如 http ...

随机推荐

  1. P2194 HXY烧情侣【Tarjan】

    前言 当时和\(GYZ\)大佬一起做这个题,他表示这个题对他很不友好(手动滑稽) 题目描述 众所周知,\(HXY\) 已经加入了 \(FFF\) 团.现在她要开始喜(sang)闻(xin)乐(bing ...

  2. HDU 2157 How many ways?【矩阵快速幂】

    题目 春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线 ...

  3. 浅谈auth模块

    目录 auth模块 什么是Auth模块 auth模块的常用方法 用户注册 扩展默认的auth_user表 auth模块 什么是Auth模块 ​ auth模块是对注册登录认证注销修改密码等方法的一种封装 ...

  4. HTTP 协议详解(二)

    前面一篇已经说过了 HTTP 的基本特性,HTTP 的发展史,前情回顾.这一篇就更详细的 HTTP 协议使用过程一些参数配置,缓存,Cookie设置相关的细节做一些梳理. 数据类型与编码 在 TCP/ ...

  5. 什么是JDK的SPI机制

    什么是SPI和API Application Programming Interface (API)? The API is the description of classes/interfaces ...

  6. c语言学习笔记第二章———入门

    B站有视频演示 2.1软件安装 推荐软件 1.dev-c++ 下载链接:(腾讯软件管家的下载地址) https://sm.myapp.com/original/Development/Dev-Cpp_ ...

  7. css图片居中,通过纯css实现图片居中的多种实现方法

    在网页布局中,图文排版是我们常用的,那么经常会遇到如何让图片居中显示呢,这篇文章将总结常用css实现图片居中的方法总结: html结构: <div class="demo" ...

  8. windows php5.5安装redis扩展,并用redis存储session

    1.确定安装版本 先通过phpinfo()查看php的Compiler.Architecture.Thread Safety,其中Thread Safety如果是enabled,那么就是线程安全(ts ...

  9. HDU 2236 无题Ⅱ

    HDU 2236 无题Ⅱ 题目大意 这是一个简单的游戏,在一个\(n*n\)的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小. solution 暴枚\(i ...

  10. 小程序checkbox-group只获取到一个值

    wx:for循环不能写在checkbox-group标签上 wx:for循环不能写在checkbox-group标签上 wx:for循环不能写在checkbox-group标签上 wx:for循环不能 ...