Django---博客项目实战
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---博客项目实战的更多相关文章
- tp5博客项目实战1
tp5博客项目实战 开发准备:环境wamp,windows系统为例.看实战博客,默认会搭建开发环境并且tp5框架已经至少有一定的基础. tp5的下载与安装 方法一:直接在官网下载拷贝到wamp你的项目 ...
- Django——博客项目
博客项目 目前的目标是构建一个基于Django的前后端完整的博客系统,首先对项目流程整理如下: 1. 分析需求 1.1. 基于用户认证组件和Ajax实现登录验证 图形验证码核心代码: 模板: < ...
- django博客项目8:文章详情页
首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容.现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样 ...
- django博客项目5:博客首页视图(2)
真正的 Django 博客首页视图 在此之前我们已经编写了 Blog 的首页视图,并且配置了 URL 和模板,让 Django 能够正确地处理 HTTP 请求并返回合适的 HTTP 响应.不过我们仅仅 ...
- django博客项目3:创建 Django 博客的数据库模型
设计博客的数据库表结构 博客最主要的功能就是展示我们写的文章,它需要从某个地方获取博客文章数据才能把文章展示出来,通常来说这个地方就是数据库.我们把写好的文章永久地保存在数据库里,当用户访问我们的博客 ...
- django博客项目2.建立 Django 博客应用
建立博客应用 我们已经建立了 Django 博客的项目工程,并且成功地运行了它.不过到目前为止这一切都还只是 Django 为我们创建的项目初始内容,Django 不可能为我们初始化生成博客代码,这些 ...
- django博客项目1.环境搭建
安装 Python Windows 下安装 Python 非常简单,去 Python 官方网站找到 Python 3 的下载地址,根据你的系统选择 32 位或者 64 位的安装包,下载好后双击安装即可 ...
- 9.28 Django博客项目(一)
2018-9-28 17:37:18 今天把博客项目 实现了注册和添加图片的功能! 放在了自己的github上面 源码! https://github.com/TrueNewBee/bbs_demo ...
- django博客项目6:Django Admin 后台发布文章
在此之前我们完成了 Django 博客首页视图的编写,我们希望首页展示发布的博客文章列表,但是它却抱怨:暂时还没有发布的文章!如它所言,我们确实还没有发布任何文章,本节我们将使用 Django 自带的 ...
- django博客项目4:博客首页视图(1)
Web 应用的交互过程其实就是 HTTP 请求与响应的过程.无论是在 PC 端还是移动端,我们通常使用浏览器来上网,上网流程大致来说是这样的: 我们打开浏览器,在地址栏输入想访问的网址,比如 http ...
随机推荐
- urllib库使用方法
这周打算把学过的内容重新总结一下,便于以后翻阅查找资料. urllib库是python的内置库,不需要单独下载.其主要分为四个模块: 1.urllib.request——请求模块 2.urllib.e ...
- ajax前后端交互原理(1)
1.Node.js简介 1.1.前后台数据交互流程 在web开发中,我们经常听说前端和后台,他们分别是做什么具体工作的呢?他们怎样交互的呢?我们得把这些基础的问题都搞明白了,才有一个大致的学习方向,首 ...
- win10 麦克风无法使用,可能是设置了权限
驱动什么的都正常,平白无故麦克风不好用了,原来是之前自己设置了麦克风权限: 把这个开关打开就可以了. (完)
- css transparent属性_css 透明颜色transparent的使用
在css中 transparent到底是什么意思呢? transparent 它代表着全透明黑色,即一个类似rgba(0,0,0,0)这样的值. 例如在css属性中定义:background:tran ...
- css实现左边定宽右边自适应的5种方法总汇
在网页布局中,通常需要实现左边定宽右边自适应布局,默认html的结构如下: <div class="box"> <div class="left&quo ...
- Xenon's Attack on the Gangs(树规)
题干 Input Output Example Test 1: Test 2: 3 5 1 2 1 2 2 3 1 3 1 4 3 5 3 10 Tips 译成人话 给n个结点,n-1条无向边.即一棵 ...
- BZOJ1294 洛谷P2566 状态压缩DP 围豆豆
传送门 题目描述 是不是平时在手机里玩吃豆豆游戏玩腻了呢?最近MOKIA手机上推出了一种新的围豆豆游戏,大家一起来试一试吧游戏的规则非常简单,在一个N×M的矩阵方格内分布着D颗豆子,每颗豆有不同的分值 ...
- 数据可视化之powerBI入门(十一)认识Power BI数据分析语言DAX
DAX是英文Data Analysis Expression的缩写,意思是数据分析表达式,从名称上就可以看出,DAX公式是用作数据分析的,事实上也确实如此,从数据分析层面认识DAX会更有助于我们理解它 ...
- 数据可视化之DAX篇(八) DAX学习:使用VAR定义变量
https://zhuanlan.zhihu.com/p/64414205 前面介绍如何使用DAX生成日期表的时候,使用了VAR,有人留言问这个VAR怎么理解,那么这篇文章就来介绍VAR以及它的用法. ...
- (四)学习了解OrchardCore笔记——将模块的名字添加到程序集的ModuleName
关于如何将模块名添加到程序集的ModuleName说简单吧也简单,说不简单吧也不简单. 简单的原因是代码只有几行,不简单的原因是这些都不是c#,都是MSbuild的代码.这可真难为我了,所以这个地方我 ...