前面我们先分析了一下,做这个项目需要的几张表,今天我们从配置文件开始一步一步去解释这么的原因

首先先来看setting.py文件:

"""
Django settings for mybbs project.Generated by 'django-admin startproject' using Django 1.11.11.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 = 'b)f=d-08hdi_w_z1^=5e9oom9#+h1a*jk-y#u!-vt$rj%5y&aj'# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = TrueALLOWED_HOSTS = []# Application definition

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','myapp.apps.MyappConfig','debug_toolbar'          #https://www.cnblogs.com/ManyQian/p/9277861.html 具体详情参考这里
]MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','debug_toolbar.middleware.DebugToolbarMiddleware',    'django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]ROOT_URLCONF = 'mybbs.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 = 'mybbs.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'),
#     }
# }

DATABASES={'default':{'ENGINE':'django.db.backends.mysql',   #数据库的配置'NAME':'duoduo','USER':'root','PASSWORD':'123','HOST':'127.0.0.1','PORT':3306,}
}# 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 = TrueUSE_L10N = TrueUSE_TZ = False  #本机的时间,不用考虑时区的问题# 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')
]# 指定一下认证使用 自定义的UserInfo表
AUTH_USER_MODEL='myapp.UserInfo'#用户上传的文件配置项
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'media')# 日志配置  Google浏览器jQuery 的URL在国内不支持
DEBUG_TOOLBAR_CONFIG ={'JQUERY_URL':'//cdn.bootcss.com/jquery/2.2.4/jquery.min.js',
}  #设置为空,就用项目中的jQuery

BASE_LOG_DIR = os.path.join(BASE_DIR, "log")LOGGING = {'version': 1,# 禁用已经存在的logger实例'disable_existing_loggers': False,# 定义日志 格式化的 工具'formatters': {'standard': {'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]''[%(levelname)s][%(message)s]'},'simple': {'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'},'collect': {'format': '%(message)s'}},# 过滤'filters': {'require_debug_true': {'()': 'django.utils.log.RequireDebugTrue',},},# 日志处理器'handlers': {'console': {'level': 'DEBUG','filters': ['require_debug_true'],  # 只有在Django debug为True时才在屏幕打印日志'class': 'logging.StreamHandler','formatter': 'simple'},'default': {'level': 'INFO','class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切'filename': os.path.join(BASE_LOG_DIR, "info.log"),  # 日志文件'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M'backupCount': 3,'formatter': 'standard','encoding': 'utf-8',},'error': {'level': 'ERROR','class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切'filename': os.path.join(BASE_LOG_DIR, "err.log"),  # 日志文件'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M'backupCount': 5,'formatter': 'standard','encoding': 'utf-8',},'collect': {'level': 'INFO','class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"),'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M'backupCount': 5,'formatter': 'collect','encoding': "utf-8"}},# logger实例'loggers': {# 默认的logger应用如下配置'': {'handlers': ['default', 'console', 'error'],  # 上线之后可以把'console'移除'level': 'DEBUG','propagate': True,},# 名为 'collect'的logger还单独处理'collect': {'handlers': ['console', 'collect'],'level': 'INFO',}},
}INTERNAL_IPS = ['127.0.0.1', ]

就是验证登陆和注册forms表单数据的合法性

from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from myapp import models#登陆的用户名
class LoginForm(forms.Form):username=forms.CharField(label='用户名',min_length=3,max_length=12,error_messages={'required':'用户名不能为空','min_length':'用户名最短3位','max_length':'用户名最长12位',},widget=forms.widgets.TextInput(attrs={'class':'form-control '}))password=forms.CharField(label='密码',min_length=4,max_length=12,error_messages={'required':'密码不能为空','min_length':'密码最短3位','max_length':'密码最长12位',},widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}))#注册的form
class RegForm(forms.Form):username=forms.CharField(label='用户名',min_length=3,max_length=12,error_messages={'required':'用户名不能为空!','min_length':'用户名最短3位','max_length':'用户名最长12位',},widget=forms.widgets.TextInput(attrs={'class':'form-control'}),)password=forms.CharField(label='密码',min_length=4,max_length=12,error_messages={'required':'密码不能为空!','min_length':'密码最短4位','max_length':'密码最长12位',},widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}))re_password = forms.CharField(label="确认密码",min_length=4,max_length=12,error_messages={"required": "确认密码不能为空!","min_length": "密码最短4位","max_length": "密码最长12位"},widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}))phone = forms.CharField(label="手机",min_length=11,max_length=11,validators=[RegexValidator(r'^\d{11}$', "手机号必须是数字"),RegexValidator(r'^1[356789][0-9]{9}$', "手机号码格式不正确")],error_messages={"required": "手机不能为空!","min_length": "手机号码11位","max_length": "手机号码11位"},widget=forms.widgets.TextInput(attrs={"class": "form-control"}))# 局部钩子def clean_username(self):value = self.cleaned_data.get("username", "")if "xxx" in value:raise ValidationError("不符合社会主义核心价值观!")elif models.UserInfo.objects.filter(username=value):raise ValidationError("用户名已存在!")else:return value# 全局钩子def clean(self):pwd = self.cleaned_data.get("password", "")re_pwd = self.cleaned_data.get("re_password", "")if re_pwd and pwd == re_pwd:return self.cleaned_dataelse:err_msg = "两次输入的密码不一致"self.add_error("re_password", err_msg)raise ValidationError(err_msg)

把表格注册到admin中

from django.contrib import  admin
from myapp import  models# Register your models here.

admin.site.register(models.Article)
admin.site.register(models.UserInfo)
admin.site.register(models.ArticleDetail)
admin.site.register(models.Blog)
admin.site.register(models.Category)
admin.site.register(models.Tag)
admin.site.register(models.Comment)
admin.site.register(models.ArticleUpDown)
admin.site.register(models.Article2Tag)

文件的结构:

我们先从注册功能开始说起:

1.html

  form_obj.字段    ------》生产html代码

2.views.py

  form_obj=forms.RegForm(request.POST)

  form_obj.is_valid() ------->返回布尔值

    1.如果返回Trun,就能拿到校验后的数据

        form_obj.cleaned_data

3.看源码分析得到钩子函数

  1.局部钩子

      def clean_字段名():

          1.return value

          2.raise ValidationError('错误信息')

  2.全局钩子

      def clean():

          1.return self.cleaned_data

          2.raise ValidationError('错误信息')

1、注册的form类

2、上传文件

  1.表单上传

    form标签两个属性

        1.method='post'

        2.enctype='multipart/form-data'

  2.AJAX上传

      1.创建一个FormData对象,使用对象的append()方法填充数据

      2.AJAX需要设置两个参数

          1.processData:false

          2.contentTyoe:false

  3.Django关于上传文件的几个配置

          1.上传文件存在哪儿?

            1.settings.py中 配置MEDIA_ROOT=os.path.join(BASE_DIR,'media')

          2.我用户怎么访问我上传的文件

            1.settings.py中配置 MEDIA_URL='/media/

            2.在urls.py中 配置 media开头的访问请求交给谁来处理'

              url(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT})

  4.浏览器图片预览

    1.FileReader对象

from django.shortcuts import render, HttpResponse, redirect
from myapp import forms, models
from django.contrib import auth
from django.http import JsonResponse
import logging# 生成一个以当前文件名命名的logger实例
logger = logging.getLogger(__name__)
# 生成一个名为collect的logger实例
collect_logger = logging.getLogger("collect")def reg(request):logger.info("又来了,小伙子!")collect_logger.info("多多来洗脚!")if request.method == "POST":ret = {"code": 0}form_obj = forms.RegForm(request.POST)logger.debug(request.FILES)if form_obj.is_valid():# 数据经过校验,没问题
            logger.debug(form_obj.cleaned_data)avatar_obj = request.FILES.get("avatar")# 创建用户form_obj.cleaned_data.pop("re_password", "")models.UserInfo.objects.create_user(avatar=avatar_obj,**form_obj.cleaned_data    #这个骚操作大家还记得?)ret["data"] = "/login/"else:# 数据没有经过校验,有问题ret["code"] = 1ret["data"] = form_obj.errorsreturn JsonResponse(ret)form_obj = forms.RegForm()return render(request, "reg.html", {"form_obj": form_obj})

reg.html文件的代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>欢迎注册</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"><style>.reg-form {margin-top: 70px;}#show-avatar {width: 80px;height: 80px;}</style>
</head>
<body><div class="container"><div class="row"><div class="col-md-6 col-md-offset-3 reg-form"><form class="form-horizontal" autocomplete="off" novalidate><div class="form-group"><label for="{{ form_obj.username.id_for_label }}"class="col-sm-2 control-label">{{ form_obj.username.label }}</label><div class="col-sm-10">{{ form_obj.username }}<span class="help-block"></span></div></div><div class="form-group"><label for="{{ form_obj.password.id_for_label }}"class="col-sm-2 control-label">{{ form_obj.password.label }}</label><div class="col-sm-10">{{ form_obj.password }}<span class="help-block"></span></div></div><div class="form-group"><label for="{{ form_obj.re_password.id_for_label }}"class="col-sm-2 control-label">{{ form_obj.re_password.label }}</label><div class="col-sm-10">{{ form_obj.re_password }}<span class="help-block"></span></div></div><div class="form-group"><label for="{{ form_obj.phone.id_for_label }}"class="col-sm-2 control-label">{{ form_obj.phone.label }}</label><div class="col-sm-10">{{ form_obj.phone }}<span class="help-block"></span></div></div><div class="form-group"><label class="col-sm-2 control-label">头像</label><div class="col-sm-10"><input accept="image/*" type="file" id="id_avatar" name="avatar" style="display: none"><label for="id_avatar"><img src="/static/img/default.png" id="show-avatar"></label>      </div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="button" class="btn btn-default" id="reg-button">注册</button></div></div></form></div></div>
</div><script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/setupAjax.js"></script><script>// 找到注册按钮绑定点击事件
    $("#reg-button").click(function () {var dataObj = new FormData();dataObj.append("username", $("#id_username").val());dataObj.append("password", $("#id_password").val());dataObj.append("re_password", $("#id_re_password").val());dataObj.append("phone", $("#id_phone").val());dataObj.append("avatar", $("#id_avatar")[0].files[0]);$.ajax({url: "/reg/",type: "POST",processData: false,contentType: false,data: dataObj,success: function (data) {console.log(data);if (data.code) {// 如果有报错信息,应该在页面的对应位置展示出来var errMsgObj = data.data;$.each(errMsgObj, function (k, v) {// k: 字段名  v:报错信息的数组// 根据字段名找对应的input标签,把错误信息添加到对应位置
                        $("#id_" + k).next(".help-block").text(v[0]).parent().parent().addClass("has-error");})} else {console.log(data.data);location.href = data.data || "/login/"}}})});// 给每一个input标签绑定focus事件,移除当前的错误提示信息
    $("input.form-control").focus(function () {$(this).next(".help-block").text("").parent().parent().removeClass("has-error");});// 头像预览
    $("#id_avatar").change(function () {// 找到你选中的那个头像文件var fileObj = this.files[0];console.log(fileObj);// 读取文件路径var fileReader = new FileReader();fileReader.readAsDataURL(fileObj);// 等图片被读取完毕之后,再做后续操作
        fileReader.onload = function () {// 设置预览图片
            $("#show-avatar").attr("src", fileReader.result);};})</script>
</body>
</html>

注册的效果图:

转载于:https://www.cnblogs.com/ManyQian/p/9276697.html

python3-开发进阶-仿博客园项目setting.py的文件的配置,admin,forms(2)相关推荐

  1. BBS(仿博客园系统)项目03(主页搭建、个人站点搭建(侧边栏分类展示、标签展示、日期归档)、文章详情页相关功能实现)...

    摘要: 主页面的搭建(导航条下面的区域) 个人站点 侧边栏分类展示 侧边栏标签展示 侧边栏日期归档 文章详情页 文章内容 文章点赞点踩 文章评论 一.主页面home.html的搭建(进一步完善) ho ...

  2. 博客园php教程,PHP仿博客园,个人博客(1)_PHP教程

    本人本科学历,自学PHP大半年多了,断断续续地,但是最终还是坚定了我的想法,将PHP继续下去,所以写这个PHP的博客是为了找个稳定的 PHP工作,不求工资多高,但求一收留之地.我能看懂大部分英语文档, ...

  3. [开源] 分享导出博客园文章成本地 Markdown 文件存储的工具

    此文主要分享了如何将自己博客园的文章自动导出到 Markdown 文档进行存储,以便在本地进行归档管理,程序中也对文章的分类.tag.代码块以及文章中的图片进行了保存处理,以便上传到自己的图. 整理后 ...

  4. python3进阶开发-第一个仿博客园的项目(1)

    首先我们要设计一下表结构: UserInfo(用户信息表) -------->一对一    ----------->Blog(博客信息表) UserInfo(用户信息表) -------- ...

  5. BBS(仿博客园系统)项目01(项目分析、表结构设计、注册功能实现)

    摘要: 需求分析 表结构设计 注册功能实现 一.需求分析: 项目需求(产品经理.架构师.开发组组长与客户谈该项目相关要求) 项目设计 (架构师需要思考:框架选择,数据库选择,主要功能模块,报价:包括工 ...

  6. android开发进阶学习博客资源

    Android开发者博客推荐 Android入门级 - 罗宪明 http://blog.csdn.net/wdaming1986 Android入门级 - 魏祝林 http://blog.csdn.n ...

  7. [Tool] 仿博客园插入代码的 WLW 插件

    一  插件相关效果图展示 插件效果图: 在 Windows Live Writer 中的效果如图: [1] [2] [3] 对应的插入代码在博客中的效果如下: [1] public static vo ...

  8. BBS+ BLOG系统(仿博客园)

    一.基本要求 作业题目:开发BBS+BLOG系统 作业需求: 1 基于ajax和用户认证组件实现登录验证 2 基于ajax和form组件实现注册功能 3 系统首页文章列表的渲染 4 个人站点页面设计5 ...

  9. 微信小程序云开发之新闻博客社区项目debug后的项目代码

    大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页:lqj_本人的博客_CSDN博客-微信小程序,html特效,vue2基础领域博主 本次文章主要时为我最近在哔哩哔哩上的新发布的视频做一个 ...

最新文章

  1. 广播站 PHP,让一实听见你的声音——“校园之声”广播站招募小记
  2. C指针5:字符串指针(指向字符串的指针)
  3. Python数据分析,抓取京东商品价格
  4. 各种测序基础知识汇总
  5. hihocoder 1689 - 推断大小关系(图论+二分)
  6. 牛客题霸 [子数组的最大累加和问题] C++题解/答案
  7. 《Leetcode》目录
  8. 519. 随机翻转矩阵
  9. Mybatis(四) 高级映射,一对一,一对多,多对多映射
  10. mac系统安装python(2.7)requests库
  11. 51单片机按键控制数码管0~9_基于proteus的51单片机开发实例24-矩阵键盘(行列式键盘)...
  12. 计算机硬件 试题,计算机硬件试题150完整版
  13. 上海展盟网络科技有限公司的 gamebox 组件注入进程导致软件崩溃
  14. django 文档参考模型
  15. 银联统一规范的收单业务消息域
  16. 【微信小程序】wx.request请求后success回调的数据无法显示到页面上
  17. 试用具体例子说明为什么在运输连接建立时要使用三次握手。说明如不这样做可能会出现什么情况。
  18. C代码如何跑起来(程序编译和预处理)
  19. openssl库android版的编译
  20. 【python 库】 pandas 教程

热门文章

  1. 前端JavaScript基础知识点
  2. artDiaLog弹出插件
  3. 一段echats 饼状图刷新代码
  4. (12) ejb学习: JPA的传播属性
  5. 记一次糟心的内网靶场实战
  6. Nginx学习笔记---ngx_table_elt_t数据结构
  7. 关于luci的几个问题二
  8. 用JADE创建多agent系统
  9. Excel中插入VBA宏处理
  10. 第16课:动手实战中文句法依存分析