转载自:http://blog.csdn.net/SKI_12/article/details/78505235
Django是基于Python的高级Web开发框架。本篇文章进行的是简单的功能的实现,后续会进行安全工具相应的开发。
下面只大致说下过程,具体的实现看源代码即可。
安装:
pip install Django==1.11.4
或直接到Github下载源代码安装
确认是否安装:python –m Django –version
创建新项目:
django-admin startproject djangotest
cd djangotest/
ls
项目目录结构如图:
manage.py:与项目进行交互的命令行工具集的入口,即项目管理器,可执行python manage.py来查看所有命令
启动服务:python manage.py runserver 8080
Django shell:python manage.py shell,自动引入项目环境,可以通过其与项目交互进行测试
djangotest目录为一个容器,包含项目的一些基本配置。
wsgi.py:Python Web Server Gateway Interface(Python服务器网关接口),即Python应用与Web服务器之间的接口。
urls.py:URL配置文件
settings.py:
BASE_DIR指定项目根目录。
SECRET_KEY即密钥,项目启动时需要用到。
DEBUG即调试,在测试时用。
ALLOWED_HOSTS即允许访问的主机名,当列表中包含localhost值时即只允许通过localhost的主机名进行访问。
INSTALLED_APPS即已安装的应用,若自己创建了新的应用则添加进去。
MIDDLEWARE即中间件,是Django自带的工具集。
ROOT_URLCONF即URL配置文件,指向urls.py文件。
TEMPLATES即模板,即关于模板的配置,模板简单地说即HTML文件。
WSGI_APPLICATION
DATABASES,数据库配置。
AUTH_PASSWORD_VALIDATORS和密码认证相关。
LANGUAGE_CODE语言编码,默认为en-us。
TIME_ZONE时区,默认为UTC。
USE_I18N
USE_L10N
USE_TZ
STATIC_URL
__init__.py:Python中声明模块的文件,默认内容为空。
创建应用:
新建blog应用:python manage.py startapp blog
接着将新建的应用添加到settings.py的INSTALLED_APPS中:
应用目录:
migrations:数据移植模块,内容自动生成
admin.py:应用的后台管理系统配置
apps.py:当前应用的配置,在Django-1.9后才自动生成
models.py:数据模块,使用ORM框架
tests.py:自动化测试模块,可再次编写测试脚本
views.py:执行响应的代码所在模块,是代码进行逻辑处理的地方,项目中大部分代码在此编写
编写views.py:
每个响应对应一个函数,因而每个函数必须返回一个响应。
函数必须有一个参数,一般约定为request。
每一个响应或函数对应一个URL。
添加内容到urls.py文件:
启动服务:python manage.py runserver 1234
访问相应的目录:
第二种配置url的方法,如注释所说:
直接修改相应的部分:
然后在blog目录下新建urls.py文件:
注意:url函数中的目录名后要添加/,否则容易出错。
再度访问:
Templates模板:
HTML文件,使用Django模板语言(Django Template Language,DTL),也可以使用第三方模板
开发模板的步骤:
1、在根目录下创建Templates目录
2、在该目录下创建HTML文件
3、在views.py中返回render()
访问:
注意点:Django会按照INSTALLED_APPS中的添加顺序来查找Templates。
解决Templates冲突的方法:在Templates目录下创建以APP名为名称的目录并将HTML文件放入新创建的目录中。
另一种创建templates目录是创建在项目的根目录中而不是在应用的目录中,然后再在该目录下创建和应用名一样的目录,再在其中创建html文件即可,注意一点的是,此时因为是创建在项目根目录中,需要在settings.py文件中设置:
Models:
通常一个Model对应数据库的一张表,是以类的形式表现出来的。
示例的models.py文件:
创建步骤:
1、在根目录下创建models.py,并引入models模块
2、创建类,继承models.Model,该类即是一张数据表
3、在类中创建字段
生成数据表:
python manage.py makemigrations app名(可选)
python manage.py migrate
查看:
在根目录的migrations目录中生成移植文件:
可以看到id字段是自动生成的主键,因为在初始创建字段时并没有指定主键。
查看SQL语句:python manage.py sqlmigrate 应用名 文件id
这里使用的是默认的sqlite3数据库,其在根目录中保存为db.sqlite3,查看其需要特定的软件,这里就不下载安装了:
页面呈现数据:
后台修改views.py,添加数据保存到数据库并从数据库读取数据返回到前端:
注意,这里添加id=10的参数是为了每次调用都是进行相同的内容进行替换保存,以避免每调用一次就新增一项数据。
前端修改index.html:
模板直接使用对象以及对象的“.”操作,如{{ article.title }}
最后访问页面即可:
Admin:
Django自带的自动化数据管理界面,被授权的用户可直接在admin中管理数据库。
配置admin:
创建超级用户:python manage.py createsuperuser
访问添加输入admin/目录即可:
可以将页面的英文修改为中文,到settings.py的LANGUAGE_CODE默认的‘en-us’改为‘zh-hans’即可:
配置应用:
在admin.py中引入自身的models模块
编辑admin.py:
刷新页面:
修改数据:
再访问:
修改数据默认名称:
接着在Article类下添加一个方法,根据Python版本,若为3以上版本则使用__str__(self)方法,若为2系列版本则使用__unicode__(self)方法,添加这个方法是为了在查询时实现相应的内容,这里是实现将显示的内容从对象改为文章标题:
再次查看:
改进:
在admin.py中添加ArticleAdmin类并通过list_display来设置文章列表显示页面中显示的列的内容:
完善Blog开发:
namespace与name参数的注意点:
1、写在include()的第二个参数位置,namespace=’blog’
先在djangotest/djangotest/urls.py的include()函数中添加namespace参数:
2、应用下则写在url()的第三个参数位置,name=’article_page’
然后到djangotest/blog/urls.py中的url()函数中添加name参数:
主要取决于是否使用include引用另一个url配置文件。
最后在HTML文件中:
template中超链接href可以用“{% url ‘app_name:url_name’ param %}”
app_name和url_name都在urls.py中配置
Blog编写页面:添加了编辑、删除、返回主页、登出等链接,具体看代码。
认证登录:
contrib模块:django.contrib.auth,默认的认证框架。
创建users:
1、示例代码如下:
- from django.contrib.auth.models import User
- user = User.objects.create_user(‘admin’, ‘demon@123.com’, ‘password’)
2、python manage.py createsuperuser
修改密码:
1、python manage.py changepassword username
2、示例代码如下:
- from django.contrib.auth.models import User
- u = User.objects.get(username=’admin’)
- u.set_password(‘newpassword’)
- u.save()
认证Users:authenticate(username=’admin’, password=’password’),成功则返回User对象,否则返回None。
Web请求中的认证:request.user.is_authenticated()
登录用户:login(request, user),需要先进行认证
登出用户:logout(request)
只允许用户登录访问:
1、检查request.user.is_authenticated()
2、login_required装饰器
先创建一个member应用,在settings.py中添加应用名,然后创建forms.py:
主要是创建用户名和密码的表单类,其中Django用widget来定义数据项的格式,这里为密码格式的文本字段。
然后创建urls.py文件:
在views.py中编写用户登录的方法user_login()。
接着对之前blog应用的views.py中的方法调用login_required()方法进行装饰:
然后再在urls.py中配置一下url即可完成登录相关的功能。
代码实现:
这里重新新建项目来实现博客系统完整的搭建。
整个项目目录架构如下:
blog目录:
admin.py:
- from django.contrib import admin
-
- from models import Article
-
-
- class ArticleAdmin(admin.ModelAdmin):
-
- list_display = ('title', 'content', 'pub_time')
- list_filter = ('pub_time',)
-
- admin.site.register(Article, ArticleAdmin)
models.py:
- from __future__ import unicode_literals
-
- from django.db import models
-
-
- class Article(models.Model):
- title = models.CharField(max_length=32, default='title')
- content = models.TextField(null=True)
- pub_time = models.DateTimeField(null=True)
-
- def __unicode__(self):
- return self.title
urls.py:
- from django.conf.urls import url
-
- from . import views
-
- urlpatterns = [
- url(r'^index/$', views.index, name='index'),
- url(r'^article/(?P[0-9]+)$', views.article_page, name='article_page'),
- url(r'^edit/(?P[0-9]+)$', views.edit_page, name='edit_page'),
- url(r'^change/$', views.change, name='change'),
- url(r'^delete/(?P[0-9]+)$', views.delete_page, name='delete_page'),
- ]
views.py:
- from django.shortcuts import render
- from django.http import HttpResponse
- from django.contrib.auth.decorators import login_required
-
- from . import models
-
-
- @login_required
- def index(request):
- articles = models.Article.objects.all()
- return render(request, 'blog/index.html', {'articles':articles})
-
- @login_required
- def article_page(request, article_id):
- article = models.Article.objects.get(pk=article_id)
- return render(request, 'blog/article_page.html', {'article':article})
-
- @login_required
- def edit_page(request, article_id):
- if str(article_id) == '0':
- return render(request, 'blog/edit_page.html')
- article = models.Article.objects.get(pk=article_id)
- return render(request, 'blog/edit_page.html', {'article':article})
-
- @login_required
- def change(request):
- title = request.POST.get('title', 'TITLE')
- content = request.POST.get('content', 'CONTENT')
- article_id = request.POST.get('article_id', '0')
- if article_id == '0':
- models.Article.objects.create(title=title, content=content)
- articles = models.Article.objects.all()
- return render(request, 'blog/index.html', {'articles':articles})
-
- article = models.Article.objects.get(pk=article_id)
- article.title = title
- article.content = content
- article.save()
- return render(request, 'blog/article_page.html', {'article':article})
-
- @login_required
- def delete_page(request, article_id):
- models.Article.objects.filter(pk=article_id).delete()
- articles = models.Article.objects.all()
- return render(request, 'blog/index.html', {'articles':articles})
member目录:
forms.py:
- from django import forms
-
- class LoginForm(forms.Form):
- username = forms.CharField()
- password = forms.CharField(widget=forms.PasswordInput)
-
urls.py:
- from django.conf.urls import url
- from django.contrib.auth import views as auth_views
-
- from . import views
-
- urlpatterns = [
- url(r'^$', views.user_login, name='login'),
- url(r'^logout-then-login/$', auth_views.logout_then_login, name='logout_then_login'),
- ]
views.py:
- from __future__ import unicode_literals
-
- from django.shortcuts import render
- from django.http import HttpResponseRedirect
- from django.contrib.auth import authenticate, login
- from django.contrib import messages
-
- from .forms import LoginForm
-
-
- def user_login(request):
- login_form = LoginForm()
- if request.method == 'POST':
- form = LoginForm(request.POST)
- if form.is_valid():
- cd = form.cleaned_data
- user = authenticate(username=cd['username'], password=cd['password'])
- if user is not None:
- if user.is_active:
- login(request, user)
- return HttpResponseRedirect('/blog/index')
- else:
- messages.error(request, "Your username and password didn't match.")
- return HttpResponseRedirect('/')
- else:
- messages.error(request, "Your username and password didn't match.")
- return HttpResponseRedirect('/')
- else:
- return render(request, 'login/user_login.html', {'login_form':login_form})
myBlog目录:
urls.py:
- from django.conf.urls import url, include
- from django.contrib import admin
-
- urlpatterns = [
- url(r'^admin/', admin.site.urls),
- url(r'^blog/', include('blog.urls', namespace='blog')),
- url(r'^', include('member.urls', namespace='member')),
- url(r'^accounts/login/', include('member.urls')),
- ]
settings.py中修改几个地方即可:
templates目录:
login目录:
user_login.html:
- >
- <head>
- <meta charset="utf-8"/>
- <title>MyBlogtitle>
- head>
- <body class="login">
- <h2>MyBlog——简单的博客系统h2>
- <div>
- <form action="{% url 'member:login' %}" method="post">
- <h3>Login to your accounth3>
- {% if messages %}
- <h5>
- {% for message in messages %}
- {{ message }}
- {% endfor %}
- h5>
- {% endif %}
- <div>
- <label>Usernamelabel>
- <div>
- <input type="text" autocomplete="off" placeholder="Username" name="username"/>
- div>
- div>
- <br/>
- <div >
- <label>Passwordlabel>
- <div>
- <input type="password" autocomplete="off" placeholder="Password" name="password"/>
- div>
- div>
- <br/>
- {% csrf_token %}
- <div>
- <button type="submit">
- Login
- button>
- div>
- form>
- div>
- <br>
- <div class="copyright">
- 2017 © SKI12
- div>
- body>
- html>
blog目录:
index.html:
- >
- <html>
- <head>
- <title>MyBlogtitle>
- head>
- <body>
- <h1>MyBlogh1>
- <a href="{% url 'blog:edit_page' 0 %}">编写博客a>
- <p>博客列表p>
- {% for article in articles %}
- <a href="{% url 'blog:article_page' article.id %}">{{ article.title }}a>
- <br/>
- {% endfor %}
- <br>
- <a href="{% url 'member:logout_then_login' %}">Logouta>
- body>
- html>
article_page.html:
- >
- <html>
- <head>
- <title>Article Pagetitle>
- head>
- <body>
- <h1>{{ article.title }}h1>
- <br/>
- <h3>{{ article.content }}h3>
- <br/>
- <br/>
- <a href="{% url 'blog:edit_page' article.id %}">Edita>
- <a href="{% url 'blog:delete_page' article.id %}">Deletea>
- <a href="{% url 'blog:index'%}">Homea>
- <a href="{% url 'member:logout_then_login' %}">Logouta>
- body>
- html>
edit_page.html:
- >
- <html>
- <head>
- <title>Edit Pagetitle>
- head>
- <body>
- <form action="{% url 'blog:change' %}" method="post">
- {% csrf_token %}
- <input type="hidden" name="article_id" value="{{ article.id | default:'0' }}">
- <label>文章标题
- <input type="text" name="title" value="{{ article.title }}" />
- label>
- <br/>
- <label>文章内容
- <input type="text" name="content" value="{{ article.content }}">
- label>
- <br/>
- <input type="submit" value="提交">
- form>
- <br/>
- <div>
- <a href="{% url 'blog:index'%}">Homea>
- <a href="{% url 'member:logout_then_login' %}">Logouta>
- div>
- body>
- html>
最终的超简版博客系统效果如图:
首先访问的时候需要登录:
登录成功后转到blog主页:
点击编写博客进入编辑页面:
点击博客文章查看博客:
简易的功能完成了,后面就进一步进行安全开发。