django搭建BBS-表单创建&注册

0824自我总结

文件结构

  • app 接口

    • migrations
    • __inint__.py
    • admin.py 管理员页面注册表单用
    • apps.py
    • bbsform.py form组件相关设置
    • models.py 模型存放
    • tests.py
    • views.py 业务逻辑
  • avatar 图片文件存储

  • BBS 项目名称以及路由存放

    • __inint__.py
    • settings.py
    • urls.py
    • wsgi.py
  • static

    • bootstrap-3.3.7-dist bootstrap文件网上下载的
    • jquery-3.4.1.min.js jq文件
  • templates 页面文件存放

一.django相关设置

settings.py

"""
Django settings for BBS project. Generated by 'django-admin startproject' using Django 1.11.22. 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 = 's0x+v@gqeoxs4ruj58cq5&*5#7on_h$n4-$hwb3cr&h(@qcmoc' # 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',
'app.apps.AppConfig',
] 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.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
} # 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' TIME_ZONE = 'UTC' 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'),
) #因为我创建模型的时候用到了user的类
AUTH_USER_MODEL='app.Userinfo'

二.模型的创建&管理页面注册

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser):
nid = models.AutoField(primary_key=True)
# 头像:FileField文件(varchar类型),default:默认值,upload_to上传的路径
avatar = models.FileField(upload_to='avatar/', default='avatar/default.png')
#跟blog表一对一
#OneToOneField本质就是ForeignKey,只不过有个唯一性约束
blog = models.OneToOneField(to='Blog', to_field='nid',null=True)
# blog = models.ForeignKey(to='Blog', to_field='nid',null=True,unique=True) class Meta:
# db_table='xxxx'
# 在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)
#跟博客是一对多的关系,关联字段写在多的一方
#to 是跟哪个表关联 to_field跟表中的哪个字段做关联, null=True 表示可以为空
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)
def __str__(self):
return self.title 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)
#文章内容 大文本
content = models.TextField()
#DateTimeField 年月日时分秒(注意跟datafield的区别)
#auto_now_add=True:插入数据会存入当前时间
#auto_now=True 修改数据会存入当前时间
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)
#多对多关系 through_fields 不能写反了:
tag = models.ManyToManyField(to='Tag', through='ArticleTOTag', through_fields=('article', 'tag'))
def __str__(self):
return self.title+'----'+self.blog.userinfo.username 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 = 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')
#布尔类型,本质也还是0和1
is_up = models.BooleanField() class Meta:
#联合唯一,一个用户只能给一片文章点赞或点踩
unique_together = (('user', 'article'),)

admin.py

from django.contrib import admin

# Register your models here.
#先导入模型
from app import models #注册表
admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Category)
admin.site.register(models.Tag)
admin.site.register(models.Article)
admin.site.register(models.ArticleTOTag)
admin.site.register(models.Commit)
admin.site.register(models.UpAndDown)

三.路由

urls.py

from django.conf.urls import url
from django.contrib import admin
#主路由导入视图内函数
from app import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register),
]

四.form组件


from django import forms
from django.forms import widgets from django.core.exceptions import ValidationError from app import models
#写一个类,继承Form 没有头像校验的字段
class Register(forms.Form):
username=forms.CharField(max_length=18,min_length=3,label="用户名",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.TextInput(attrs={'class':'form-control'}),
)
password=forms.CharField(max_length=18,min_length=3,label="密码",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.PasswordInput(attrs={'class':'form-control'}),
)
re_pwd=forms.CharField(max_length=18,min_length=3,label="确认密码",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.PasswordInput(attrs={'class':'form-control'}),
)
email=forms.EmailField(max_length=18,min_length=3,label="邮箱",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.EmailInput(attrs={'class':'form-control'}),
)
#局部钩子,局部校验
def clean_username(self):
#取出name对应的值
name=self.cleaned_data.get('username')
# if name.startswith('sb'):
# #校验不通过,抛异常
# raise ValidationError('不能以sb开头')
# #校验通过,直接return name值
# else:
# return name
user=models.UserInfo.objects.filter(username=name).first()
if user:
#用户存在,抛异常
raise ValidationError('用户已经存在')
else:
return name
#全局钩子,全局校验 def clean(self):
pwd=self.cleaned_data.get('password')
r_pwd=self.cleaned_data.get('re_pwd')
if pwd==r_pwd:
#校验通过,返回清洗后的数据
return self.cleaned_data
else:
#校验不通过,抛异常
raise ValidationError('两次密码不一致')

五.业务逻辑&html页面

1.业务逻辑

views.py

from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse
#Image导入
#ImageDraw在图片上写字
#ImageFont 写字的格式
from PIL import Image,ImageDraw,ImageFont
import random
# 相当于把文件以byte格式存到内存中
from io import BytesIO from django.contrib import auth from app.bbsforms import Register
from app import models from django.db.models import Count
from django.db.models.functions import TruncMonth
from django.db.models import F # Create your views here.
def register(request):
if request.method=='GET':
form=Register()
return render(request,'register.html',{'form':form})
elif request.is_ajax():
response={'code':100,'msg':None}
form = Register(request.POST)
if form.is_valid():
#校验通过的数据
clean_data=form.cleaned_data
#把re_pwd剔除
clean_data.pop('re_pwd')
#取出头像
avatar=request.FILES.get('avatar')
if avatar:
#因为用的是FileField,只需要把文件对象赋值给avatar字段,自动做保存
clean_data['avatar']=avatar
user=models.UserInfo.objects.create_user(**clean_data)
if user:
response['msg'] = '创建成功'
else:
response['code'] = 103
# 把校验不通过的数据返回
response['msg'] = '创建失败'
else:
response['code']=101
#把校验不通过的数据返回
response['msg']=form.errors
print(type(form.errors))
return JsonResponse(response,safe=False)

2.网页

常见的几条函数的封装

jq.html

<script src="/static/jquery-3.4.1.min.js"></script>

bootstrap.html

<link rel="stylesheet" href='/static/bootstrap-3.3.7-dist/css/bootstrap.min.css'>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>

主视图

register.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>注册</title>
{% include 'bootstrap.html' %}
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3"> <h1>注册</h1>
<form id="my_form">
{% csrf_token %}
{% for foo in form %}
<div class="form-group">
{#foo.auto_id 就是foo生成的input的id#}
<label for="{{ foo.auto_id }}">{{ foo.label }}</label>
{{ foo }} <span style="color: red" class="error pull-right"></span>
</div> {% endfor %}
<div class="form-group">
<label for="id_file">头像
<img src="/static/img/default.png" width="80" height="80" style="margin-left: 20px" id="id_img">
</label> <input type="file" name="file" id="id_file" style="display: none">
</div>
<input type="button" class="btn btn-success" value="提交" id="id_submit">
</form>
</div>
</div>
</div>
</body>
{% include 'jq.html' %}
<script>
//当该控件发生变化,响应该事件
$("#id_file").change(function () {
//alert(1)
//取到文件对象
var file = $("#id_file")[0].files[0]
//放到img控件上,借助于filereader 中间的东西,文件阅读器
//生成一个文件阅读器对象赋值给filereader
var filereader = new FileReader()
//把文件读到filereader对象中
//读文件需要时间,需要文件读完再去操作img
filereader.readAsDataURL(file) filereader.onload = function () {
$("#id_img").attr('src', filereader.result)
} })
$("#id_submit").click(function () { //ajax 上传文件 var formdata = new FormData()
//一个一个往里添加,稍微复杂,用简便方法
// formdata.append('name',$("#id_name").val())
// formdata.append('pwd',$("#id_pwd").val()) //简便方法
//form 对象的serializeArray,它会把form中的数据包装到一个对象中(不包含文件)
var my_form_data = $("#my_form").serializeArray()
//console.log(typeof my_form_data)
//console.log(my_form_data)
//jq的循环,传两个参数,第一个是要循环的对象,第二个参数是一个匿名函数
$.each(my_form_data, function (k, v) {
{#console.log(k)#}
{#console.log(v)#}
formdata.append(v.name, v.value)
})
formdata.append('avatar', $("#id_file")[0].files[0]) $.ajax({
url: '/register/',
type: 'post',
processData: false, //告诉jQuery不要去处理发送的数据
contentType: false,// 告诉jQuery不要去设置Content-Type请求头
data: formdata,
success: function (data) {
//console.log(data)
if(data.code==100){
location.href='/login/'
}else if(data.code==101){
$.each(data.msg,function (k,v) {
console.log(k)
console.log(v)
$("#id_"+k).next().html(v[0])
if(k=='__all__'){
$("#id_re_pwd").next().html(v[0])
} }) }
//定时器
setTimeout(function () {
$(".error").html("")
},3000)
} })
}) </script>
</html>

django搭建BBS-表单创建&注册的更多相关文章

  1. Django 11 form表单(状态保持session、form表单及注册实现)

    Django 11 form表单(状态保持session.form表单及注册实现) 一.状态保持 session 状态保持 #1.http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状 ...

  2. Django——11 状态保持 form表单 登陆注册样例

    Django 状态保持 用户状态例子 实现注册登陆实例 django forms 表单的使用 注册功能 登陆功能   状态保持cookie和session 1.http协议是无状态的:每次请求都是一次 ...

  3. 第二十二章 Django会话与表单验证

    第二十二章 Django会话与表单验证 第一课 模板回顾 1.基本操作 def func(req): return render(req,'index.html',{'val':[1,2,3...]} ...

  4. Django--分页器(paginator)、Django的用户认证、Django的FORM表单

    分页器(paginator) >>> from django.core.paginator import Paginator >>> objects = ['joh ...

  5. Django中的表单

    目录 表单 Django中的表单 用表单验证数据 自定义验证 表单 HTML中的表单是用来提交数据给服务器的,不管后台服务器用的是 Django  还是 PHP还是JSP还是其他语言.只要把 inpu ...

  6. Django的form表单

    html的form表单 django中,前端如果要提交一些数据到views里面去,需要用到 html里面的form表单. 例如: # form2/urls.py from django.contrib ...

  7. 雷林鹏分享:jQuery EasyUI 表单 - 创建树形下拉框

    jQuery EasyUI 表单 - 创建树形下拉框 树形下拉框(ComboTree)是一个带有下列树形结构(Tree)的下拉框(ComboBox).它可以作为一个表单字段进行使用,可以提交给远程服务 ...

  8. Django之mysql表单操作

    在Django之ORM模型中总结过django下mysql表的创建操作,接下来总结mysql表记录操作,包括表记录的增.删.改.查. 1. 添加表记录 class UserInfo(models.Mo ...

  9. 转载:Django之form表单

    转载: 一.使用form类创建一个表单 先定义好一个RegForm类: forms.py from django import forms # 导入forms类 class NameForm(form ...

随机推荐

  1. windows系统下安装JDK8

    学习JAVA,必须得安装一下JDK(java development kit java开发工具包),配置一下环境就可以学习JAVA了,下面是下载和安装JDK的教程: 一.下载 1.JDK下载地址: h ...

  2. 使用openlivewriter编写cnblogs博客

    下载OpenLiveWriter 下载地址:http://openlivewriter.org/ 安装OpenLiveWriter 1.账号配置 2.常规操作,省略- 安装高亮插件 1.下载插件:ht ...

  3. Spotlight on Oracle注册码破解(亲测可用)

    了解到该工具监控十分强大,该工具优点: 我就是为了监控一个Oracle数据库,查阅各种资料,真是费了十牛二虎之力,才破解完成.#_# 在客户端安装好了,连接监控的服务器,提示得要注册码,这外国的软件基 ...

  4. [大数据学习研究] 3. hadoop分布式环境搭建

    1. Java安装与环境配置 Hadoop是基于Java的,所以首先需要安装配置好java环境.从官网下载JDK,我用的是1.8版本. 在Mac下可以在终端下使用scp命令远程拷贝到虚拟机linux中 ...

  5. 《clean code》讲述代码中的道,而不是术

    Clean code 看<clean code>一书,学习高手写出的代码,简单高效的代 1.目标 Bjarne Stroustrup:优雅且高效:直截了当:减少依赖:只做好一件事 Grad ...

  6. 增删改查——DBUtils

    利用QueryRunner类实现对数据库的增删改查操作,需要先导入jar包:commons-dbutils-1.6.利用QueryRunner类可以实现对数据步骤的简化. 1.添加 运用JDBC工具类 ...

  7. MYSQL之查询篇

    2. 数据库操作 数据库在创建以后最常见的操作便是查询 2.1 查询 为了便于学习和理解,我们预先准备了两个表分别是stduents表和classes表两个表的内容和结构如下所示 students表的 ...

  8. Vue最全指令大集合————VUE

    # Vue指令大集合(无slot) #### 包含内容: 1. v-cloak2. v-html3. v-text4. v-bind5. v-show6. v-model7. v-for8. v-if ...

  9. java架构之路-(设计模式)五种创建型模式之单例模式

    设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...

  10. 《Maven实战》读书笔记

    一.Maven使用入门 POM(Project Object Model,项目对象模型),定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等等 二.坐标和依赖 1.何为Maven坐标 Mave ...