当前位置: 首页 > news >正文

Django+Nginx+uwsgi搭建自己的博客(三)

本来打算在这篇博文中介绍Users App的前端部分的,但写着写着就发现还需要铺垫很多东西才能把整个项目串的比较流畅些,因此这篇就继续介绍了后端的一些东西,前端的部分只好跳票到下一篇了~)

在上一篇博文中,向大家介绍了User App的model以及后台功能实现。这篇博文将会介绍对Users App的一些修改、myblog/settings.py文件中的配置以及Django后台程序的使用。

首先来看对Users App的一些修改,主要体现在对上篇博文中的views.py中的userregister函数以及userForm.py中的UserRegisterForm类中。我们之前的UserRegisterForm类是基于Form类实现的表单,在userregister函数中需要逐项获取表单中每个栏位的值,并建立对应的用户;此外,由于头像文件的存在,我们还需自己处理文件的上传问题,较为繁琐。因此,我们现在采用Django提供的另一种表单——ModelForm来建立UserRegisterForm表单。

ModelForm表单与一般表单的区别在于,其可以根据对应的Model直接生成Model相对应的表单,适合建立各种数据;此外,对于Model中的FileField/ImageField,ModelForm也可根据其upload_to参数自动将文件存储在相应的路径下,十分方便。

由于ModelForm与Model的字段有对应的约束关系,因此我们要对Users的Model进行一下修改:

 

[python] view plain copy
print ?
  1. # users/models.py  
  2. # -*- coding=utf-8 -*-  
  3. from django.db import models  
  4. import datetime  
  5. from django.utils import timezone  
  6. import PIL  
  7. # Create your models here.  
  8. class Users(models.Model):  
  9.     username = models.CharField(max_length=8,primary_key=True,unique=True,verbose_name=u'用户名')  
  10.     password = models.CharField(max_length=16,verbose_name=u'密码')  
  11.     logoimage = models.ImageField(upload_to='logoimages',null=True,blank=True,verbose_name=u'头像')  
  12.     # new field  
  13.     birthday = models.DateTimeField(null=True,blank=True,verbose_name=u'生日')  
  14.     email = models.CharField(max_length=255,null=True,blank=True,verbose_name=u'电子邮件')  
  15.     mobilephone = models.CharField(max_length=11,null=True,blank=True,verbose_name=u'手机号码')  
  16.     # new field end  
  17.     registertime = models.DateTimeField(default=timezone.now())  
# users/models.py
# -*- coding=utf-8 -*-
from django.db import models
import datetime
from django.utils import timezone
import PIL
# Create your models here.
class Users(models.Model):
    username = models.CharField(max_length=8,primary_key=True,unique=True,verbose_name=u'用户名')
    password = models.CharField(max_length=16,verbose_name=u'密码')
    logoimage = models.ImageField(upload_to='logoimages',null=True,blank=True,verbose_name=u'头像')
    # new field
    birthday = models.DateTimeField(null=True,blank=True,verbose_name=u'生日')
    email = models.CharField(max_length=255,null=True,blank=True,verbose_name=u'电子邮件')
    mobilephone = models.CharField(max_length=11,null=True,blank=True,verbose_name=u'手机号码')
    # new field end
    registertime = models.DateTimeField(default=timezone.now())
与上篇博文中的Model相比,除registertime字段外,每个字段名都加了verbose_name的参数,该参数将作为ModelForm的标签使用;此外,使用timezone.now()函数为registertime设置默认值,用于直接生成用户注册时间。
在Model修改好后,我们依然使用(一)中的命令对Model进行更新,以将新的改动应用到数据库中。随后,我们就可以开始设计ModelForm了。

 

下面是修改后的UserRegisterForm表单:

 

[python] view plain copy
print ?
  1. # userForm.py  
  2. #-*- coding=utf-8 -*-  
  3. from django import forms  
  4. from django.forms import ModelForm  
  5. from .models import Users  
  6.   
  7. # UserLoginForm不需改变  
  8.   
  9. class UserRegisterForm(ModelForm):  
  10.     class Meta:  
  11.         model = Users  
  12.         fields = ['username','password','logoimage',  
  13.                   'birthday','email','mobilephone']  
# userForm.py
#-*- coding=utf-8 -*-
from django import forms
from django.forms import ModelForm
from .models import Users

# UserLoginForm不需改变

class UserRegisterForm(ModelForm):
    class Meta:
        model = Users
        fields = ['username','password','logoimage',
                  'birthday','email','mobilephone']

现在的UserRegisterForm就是一个基于Users Model的表单。每个自定义的ModelForm都作为ModelForm的子类,在其中通过内部类的方式定义表单所依据的Model以及表单要呈现的字段。在UserRegisterForm中,model = Users表明了该表单依据于Users这个Model,而fields列表决定了表单要呈现哪些字段。

 

有了新的UserRegisterForm,我们的userregister函数可以大大简化,如下所示:

 

[python] view plain copy
print ?
  1. # 简化后的userrgeister函数  
  2. def userregister(request):  
  3.     if request.method == 'POST':  
  4.         form = UserRegisterForm(request.POST,request.FILES)  
  5.         if form.is_valid():  
  6.             form.save()  
  7.             result_info = 'success'  
  8.             return HttpResponseRedirect(reverse('users:registerResult', kwargs={'info': result_info}))  
  9.     else:  
  10.         form = UserRegisterForm()  
  11.     return render(request,'users/userregister.html',{'form':form})  
# 简化后的userrgeister函数
def userregister(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST,request.FILES)
        if form.is_valid():
            form.save()
            result_info = 'success'
            return HttpResponseRedirect(reverse('users:registerResult', kwargs={'info': result_info}))
    else:
        form = UserRegisterForm()
    return render(request,'users/userregister.html',{'form':form})
在现在的函数中,我们只是建立了新的UserRegisterForm表单,使用POST和FILES分别接收数据和文件。随后,我们调用is_valid()函数对表单填写的数据进行验证,而在验证通过后,即可调用save()方法将表单的数据以及文件存入数据库中,同时完成文件的上传,完成用户的注册。
好了,借助ModelForm的强大功能,我们现在大大简化了userregister函数,现在可以开始调整myblog/settings.py中的相关配置了。

 

myblog/settings.py是工程整体的配置文件,每个工程只有一个,因此下文可以简称为settings.py。该文件中存储了整个工程中的相关配置,如使用的App名称、使用的时区、文件上传路径等等信息。下面来具体的看一下settings.py中的关键配置:

 

[python] view plain copy
print ?
  1. # settings.py  
  2. # -*- coding=utf-8 -*-  
  3. import os  
  4.   
  5. # Build paths inside the project like this: os.path.join(BASE_DIR, ...)  
  6. BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  
  7.   
  8. # Quick-start development settings - unsuitable for production  
  9. # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/  
  10.   
  11. # SECURITY WARNING: keep the secret key used in production secret!  
  12. SECRET_KEY = '系统自动生成的私钥'  
  13.   
  14. # SECURITY WARNING: don't run with debug turned on in production!  
  15. DEBUG = False   
  16.   
  17. ALLOWED_HOSTS = ['*']   
  18.   
  19. # Application definition  
  20.   
  21. INSTALLED_APPS = [  
  22.     'users.apps.UsersConfig',  
  23.     'django.contrib.admin',  
  24.     'django.contrib.auth',  
  25.     'django.contrib.contenttypes',  
  26.     'django.contrib.sessions',  
  27.     'django.contrib.messages',  
  28.     'django.contrib.staticfiles',  
  29. ]  
  30.   
  31. MIDDLEWARE = [  
  32.     'django.middleware.security.SecurityMiddleware',  
  33.     'django.contrib.sessions.middleware.SessionMiddleware',  
  34.     'django.middleware.common.CommonMiddleware',  
  35.     'django.middleware.csrf.CsrfViewMiddleware',  
  36.     'django.contrib.auth.middleware.AuthenticationMiddleware',  
  37.     'django.contrib.messages.middleware.MessageMiddleware',  
  38.     'django.middleware.clickjacking.XFrameOptionsMiddleware',  
  39. ]  
  40.   
  41. ROOT_URLCONF = 'myblog.urls'  
  42.   
  43. TEMPLATES = [  
  44.     {  
  45.         'BACKEND''django.template.backends.django.DjangoTemplates',  
  46.         'DIRS': ['myblog/templates',],  
  47.         'APP_DIRS'True,  
  48.         'OPTIONS': {  
  49.             'context_processors': [  
  50.                 'django.template.context_processors.debug',  
  51.                 'django.template.context_processors.request',  
  52.                 'django.contrib.auth.context_processors.auth',  
  53.                 'django.contrib.messages.context_processors.messages',  
  54.             ],  
  55.         },  
  56.     },  
  57. ]  
  58. WSGI_APPLICATION = 'myblog.wsgi.application'  
  59.   
  60. # Database  
  61. # https://docs.djangoproject.com/en/1.11/ref/settings/#databases  
  62.   
  63. DATABASES = {  
  64.     'default': {  
  65.         'ENGINE''django.db.backends.sqlite3',  
  66.         'NAME': os.path.join(BASE_DIR, 'blog.sqlite'),  
  67.     }  
  68. }  
  69.   
  70. # Password validation  
  71. # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators  
  72.   
  73. AUTH_PASSWORD_VALIDATORS = [  
  74.     {  
  75.         'NAME''django.contrib.auth.password_validation.UserAttributeSimilarityValidator',  
  76.     },  
  77.     {  
  78.         'NAME''django.contrib.auth.password_validation.MinimumLengthValidator',  
  79.     },  
  80.     {  
  81.         'NAME''django.contrib.auth.password_validation.CommonPasswordValidator',  
  82.     },  
  83.     {  
  84.         'NAME''django.contrib.auth.password_validation.NumericPasswordValidator',  
  85.     },  
  86. ]  
  87.   
  88. # Internationalization  
  89. # https://docs.djangoproject.com/en/1.11/topics/i18n/  
  90.   
  91. LANGUAGE_CODE = 'en-us'  
  92.   
  93. TIME_ZONE = 'Asia/Shanghai' #  
  94.   
  95. USE_I18N = True  
  96.   
  97. USE_L10N = True  
  98.   
  99. USE_TZ = False  
  100.   
  101.   
  102. # Static files (CSS, JavaScript, Images)  
  103. # https://docs.djangoproject.com/en/1.11/howto/static-files/  
  104.   
  105. STATIC_URL = '/static/'  
  106. STATIC_ROOT = os.path.join(BASE_DIR,'static/')  
  107. MEDIA_ROOT = os.path.join(BASE_DIR,'media/')  
  108. MEDIA_URL = '/media/'  
# settings.py
# -*- coding=utf-8 -*-
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 = '系统自动生成的私钥'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False 

ALLOWED_HOSTS = ['*'] 

# Application definition

INSTALLED_APPS = [
    'users.apps.UsersConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

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 = 'myblog.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['myblog/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 = 'myblog.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, 'blog.sqlite'),
    }
}

# 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 = 'Asia/Shanghai' #

USE_I18N = True

USE_L10N = True

USE_TZ = False


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static/')
MEDIA_ROOT = os.path.join(BASE_DIR,'media/')
MEDIA_URL = '/media/'
在settings.py中,这几个配置比较重要,需要我们自己来设置或在配置中使用:

 

BASE_DIR:工程的根路径,为Django自动生成,无需修改,但在后面的配置中需要使用;

DEBUG:Debug模式开关,默认为True,此时若后台server有错导致访问失败,将在浏览器中显示详细的错误信息,以便于开发者调试;若改为False,则当有错误时只会显示错误代码。

ALLOWED_HOST:允许访问的主机。'*'表示任何主机都可以访问;当访问的主机与ALLOWED_HOST不匹配时,将会发生SuspiciousOperation错误。默认情况下,DEBUG=True且ALLOWED_HOST为空时,表示只有'localhost','127.0.0.1'与'[::1]'这三个主机可以访问页面(即本地访问)。

INSTALLED_APPS:该list里存储了工程中要使用的App,每个App需要在这里注册后方可使用。在这里,我们添加了users.apps.UserConfig这一项,从而将Users App注册在工程中。

TEMPLATES中的DIRS参数:决定了工程中前端模板的存放路径。

TIME_ZONE:时区。默认为UTC,即该工程中涉及到时间的相关函数都以UTC时间来计算;在这里我们使用Asia/Shanghai来把时区更改为北京时间。

MEDIA_ROOT:用户上传文件的存储路径。

MEDIA_URL:用户上传文件的URL前缀,如头像文件存储于media/logomiages路径下,则网页中的img标签src属性为/media/logoimages/logo.jpg,开头的/media/即为MEDIA_URL的值。

STATIC_ROOT:工程中静态文件的存储路径。

 

STATIC_URL:工程中静态文件的URL前缀,与MEDIA_URL意义相似。

在设置好settings.py文件后,我们就可以开始设计我们的主页了。与Users App一样,我们还是要在myblog目录下的views.py和urls.py中编写函数以及配置对应的url。myblog/urls.py内容如下所示:

 

[python] view plain copy
print ?
  1. # myblog/urls.py  
  2. from django.conf.urls import url  
  3. from django.contrib import admin  
  4. from django.conf.urls import include  
  5. from . import views  
  6.   
  7. urlpatterns = [  
  8.     url(r'^$',views.index,name='index'),  
  9.     url(r'^users/',include('users.urls')),  
  10.     url(r'^admin/', admin.site.urls),  
  11.   
  12. ]  
# myblog/urls.py
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
from . import views

urlpatterns = [
    url(r'^$',views.index,name='index'),
    url(r'^users/',include('users.urls')),
    url(r'^admin/', admin.site.urls),

]
在urlpatterns list中,第一行与Users中的urls.py中的内容一样,将地址为127.0.0.1的url映射到index view函数中;而第二行的将所有users/开头的url全部通过include('users.urls')的方式交与Users App中的urls.py文件解析映射;最后一行是Django自己的后台页面,可以通过127.0.0.1/admin访问。

 

在myblog/views.py中,我们编写index函数作为主页的后台程序:

 

[python] view plain copy
print ?
  1. # myblog/views.py  
  2. # -*- coding=utf-8 -*-  
  3. from django.shortcuts import render  
  4. from users.models import Users  
  5.   
  6. def index(request):  
  7.     try:  
  8.         username = request.session['username']  
  9.         user = Users.objects.get(username=username)  
  10.     except KeyError:  
  11.         user = Users.objects.get(username='anony')  
  12.     except Users.DoesNotExist:  
  13.         user = Users.objects.get(username='anony')  
  14.       
  15.     # username = request.session.get('username')  
  16.     content = {'curruser':user  
  17.                }  
  18.     return render(request, 'myblog/index.html', content)  
# myblog/views.py
# -*- coding=utf-8 -*-
from django.shortcuts import render
from users.models import Users

def index(request):
    try:
        username = request.session['username']
        user = Users.objects.get(username=username)
    except KeyError:
        user = Users.objects.get(username='anony')
    except Users.DoesNotExist:
        user = Users.objects.get(username='anony')
    
    # username = request.session.get('username')
    content = {'curruser':user
               }
    return render(request, 'myblog/index.html', content)

该主页通过request.session['username']获取到当前的登录用户,并将其传回前端页面进行处理。我们会通过Django后台程序建立一个名为anony的用户来作为没有用户登录情况下的默认用户,也即匿名用户。

 

为了使用Django后台程序,我们首先需要建立一个超级用户:

 

[python] view plain copy
print ?
  1. python manage.py createsuperuser  
python manage.py createsuperuser

 

输入命令后,按照提示一步步输入用户名、密码以及邮箱后,我们就建立好了超级用户。

为了将Users App注册到admin页面,我们需要在users/admin.py中写入以下内容:

 

[python] view plain copy
print ?
  1. # users/admin.py  
  2. from django.contrib import admin  
  3. from .models import Users  
  4. # Register your models here.  
  5. admin.site.register(Users)  
# users/admin.py
from django.contrib import admin
from .models import Users
# Register your models here.
admin.site.register(Users)
admin.site.register(Users)这句会将Users App注册到Django的后台页面,使得我们可以直接通过后台页面添加、修改或删除Users App的数据。

 

随后,我们可以在myblog目录下输入以下命令,启动在Debug模式下的server:

 

[python] view plain copy
print ?
  1. python manage.py runserver  
python manage.py runserver
在启动好server后,我们就可以在浏览器中输入127.0.0.1:8000/admin进入Django的后台页面了,如下图所示:

 


(注意,由于此时我已经完成了uwsgi+nginx的部署,所以我的路径是127.0.0.1/admin而不是127.0.0.1:8000/admin。若没有在nginx上部署的,而是使用runserver命令启动Django自己的服务器,则地址仍然是127.0.0.1:8000/admin)。

在该页面中输入我们注册好的超级用户的用户名和密码,就进入了后台程序,如图所示:


Django的后台网页大致分为三部分:AUTHENTICATION AND AUTHORIZATION组是系统自动生成的组,在其中的Users中可以看到我们刚才定义好的超级用户的信息;而Group显然是用户组;在AUTHENTICATION AND AUTHORIZATION组之下是两个我们自己定义的App,一个是我们的Users App,可以看到该App下的Users Model;而另一个是我们之后会建立的Blogs App以及其下的两个Model;在这三个组的右侧则是我们通过后台操作的历史记录,可以看到我们曾经对哪些Model进行过操作。

现在我们可以添加一个anony的用户来作为我们的匿名用户了。点击Userss右边的+Add按钮,进入添加数据界面,如图所示:


在这个页面中,我们仅需把相关的数据填写好,然后点击右下角的SAVE按钮,即可通过后台来建立我们的匿名用户了。

稍微总结一下:在这篇博文中主要讲了三个地方:1、对上一篇的Users App进行了一些修改,简化了用户注册操作;2、介绍了settings.py文件中的相关配置,为以后的开发打下基础;3、设计了主页的后台程序index,以及介绍了Django的后台页面的使用。

好了,写了近3个小时发现这篇的内容已经很多了,因此前端部分也只能跳票到下一篇博文了,请大家继续关注~

转载于:https://www.cnblogs.com/xiaoyaojinzhazhadehangcheng/p/8360436.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • turtlebot3_waffle 之PC工作环境搭建过程记录
  • Flask 安装 快速入门
  • To the Max
  • mysql--------char 和 varchar 的区别
  • WMI应用(一个系统自带的测试WMI语句的工具)
  • Flask从入门到精通之在视图函数中处理表单
  • js原型链和继承
  • vue实例相关2
  • Django-Ajax
  • ChildProcAppHandle记录(spark-2.2.0)
  • ivew语法中'${}`的用法
  • 常用CSS技术收藏
  • C#中out和ref之间的区别
  • 我在GitHub Pages托管静态博客啦~
  • php实现文件上传
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • HTTP--网络协议分层,http历史(二)
  • JS实现简单的MVC模式开发小游戏
  • Mithril.js 入门介绍
  • Netty源码解析1-Buffer
  • python学习笔记 - ThreadLocal
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • Theano - 导数
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 今年的LC3大会没了?
  • 利用DataURL技术在网页上显示图片
  • 模型微调
  • 三栏布局总结
  • 微信公众号开发小记——5.python微信红包
  • 项目管理碎碎念系列之一:干系人管理
  • 用quicker-worker.js轻松跑一个大数据遍历
  • MyCAT水平分库
  • ​第20课 在Android Native开发中加入新的C++类
  • # 职场生活之道:善于团结
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #LLM入门|Prompt#3.3_存储_Memory
  • #Spring-boot高级
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (C语言)逆序输出字符串
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (二)十分简易快速 自己训练样本 opencv级联lbp分类器 车牌识别
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (实战篇)如何缓存数据
  • (转载)Linux网络编程入门
  • .form文件_一篇文章学会文件上传
  • .gitignore文件---让git自动忽略指定文件
  • .libPaths()设置包加载目录
  • .NET 4.0中的泛型协变和反变
  • .NET Core 2.1路线图
  • .NET Core 项目指定SDK版本