在过去的几天时间里面,我主要把精力集中在研究SDUOJ
的源码构架,同时自己尝试去使用Django
建立一个简单的个人博客从而加强自己对Django
框架的理解
主要参考:Django的是如何工作的
首先,查看SDUOJ
的基本代码框架:
可以看到
SDUOJ
中含有一个APP,
OJ
,同时
SDUOJ
相关的设置文件等保存在
OnlineJudge
中。
在models.py
文件中,我们可以看到OnlineJudge
的数据库设计,而在settings.py
之中保存了连接数据库的相关设置。
#part of settings.py
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'OJ',
# 'kronos'
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'OnlineJudge.urls'
# TEMPLATES_DIRS = (os.path.join(BASE_DIR, 'templates'),)
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 = 'OnlineJudge.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'oj',
'USER': 'oj',
'PASSWORD': '***',
}
}
在urls.py
中保存了相关url
的设置,负责网站的页面跳转:
url(r'^$', views.home),
url(r'^login/$', views.login),
url(r'^register/$', views.register),
url(r'^logout/$', views.logout),
url(r'^problem/$', views.problem),
url(r'^problem/([0-9]+)/$', views.problem_detail),
url(r'^problem/([0-9]+)/submit/$', views.problem_submit),
url(r'^status/$', views.status),
url(r'^contest/$', views.contest),
url(r'^contest/([0-9]+)/$', views.contest_detail),
url(r'^contest/([0-9]+)/get_problem$', views.contest_get_problem),
url(r'^contest/([0-9]+)/status/$', views.contest_status),
url(r'^contest/([0-9]+)/submit/$', views.contest_submit),
url(r'^contest/([0-9]+)/time/$', views.contest_time),
url(r'^contest/([0-9]+)/rank/$', views.contest_rank),
#url(r'^contest/([0-9]+)/clar/$', views.contest_clar),
url(r'^admin/', include(admin.site.urls)),
url(r'^rank/$', views.rank),
url(r'^about/$', views.about),
url(r'^show_source/$', views.show_source),
url(r'^change_name/$', views.change_name),
url(r'^profile/$', views.profile),
在views.py
主要负责将前端所需要的数据从数据库中提取出来以及将前端所需要保存的数据保存到数据库中,相当于一个中间件,而这个也是网站的主要部分,负责处理各种用户请求
在了解了Django
基本的框架之后,下面我将要尝试去建立自己的博客,为以后编写SDUVJ
做铺垫
创建工程项目###
D:/djpy> django-admin.py startproject mysite
同时,在项目目录下创建一个APP:bolg
D:/pydj> cd mysite
D:/djpy/mysite$ python manage.py startapp blog
创建成功的项目如下:
初始化admin后台数据库###
由于Django自带相应的后台管理工具Admin
,所以在这里我也采用自带的后台管理工具
同时,我选择MySQL作为我的数据库,因此需要在settings.py
进行想过的配置:
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST' : '127.0.0.1',
'PORT': '3306',
'USER':'root',
'PASSWORD':'***',
}
}
然后在settings.py
中对blog
进行设置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',#ADD
]
创建数据库,在这里需要注意的是由于Django的版本的不同,创建数据库所使用的命令也有所区别:
#Django 1.6x以下版本:
python manage.py syncdb
#Django 1.7以上版本:
python manage.py makemigrations
python manage.py migrate
因为我的Django版本为1.11
,所以我使用第二种创建方式:
#python manage.py makemigrations
C:\Users\George_Li\Desktop\SDU-OJ\DjangoTest\mysite>python manage.py makemigrations
Migrations for 'blog':
blog\migrations\0001_initial.py
- Create model Person
#python manage.py migrate
C:\Users\George_Li\Desktop\SDU-OJ\DjangoTest\mysite>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying blog.0001_initial... OK
Applying sessions.0001_initial... OK
这里需要注意的是由于Python2.7
之后不再支持MySQLdb
所以需要使用PyMySQL
来连接数据库,这里需要对项目的__init__.py
文件进行配置:
import pymysql
pymysql.install_as_MySQLdb()
到此,对于基本的平台搭建就基本完成了,接下来可以对基本的页面进行设计了
针对博客设计Model###
打开models.py
并针对博客要求进行设计:
from django.db import models
from django.contrib import admin
# Create your models here.
class BlogsPost(models.Model):
title = models.CharField(max_length = 150)
body = models.TextField()
timestamp = models.DateTimeField()
admin.site.register(BlogsPost)
然后重新创建一次数据库,使用相同的语句:
由于之间已经建立过一次数据库,因此针对没有发生改变的内容,Django没有再次操作
C:\Users\George_Li\Desktop\SDU-OJ\DjangoTest\mysite>python manage.py makemigrations
Migrations for 'blog':
blog\migrations\0002_auto_20170519_0010.py
- Create model BlogsPost
- Delete model Person
C:\Users\George_Li\Desktop\SDU-OJ\DjangoTest\mysite>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0002_auto_20170519_0010... OK
此时再次启动服务器,可以发现后台发生改变:
这个时候我们已经能够在后台中创建博客了
前端界面的优化###
由于前端没有模板,因此显得特别简陋,而我也希望能够在自己设计前端界面的同时,积累经验
首先,打开mysite/blog/models.py
文件,做出如下修改:
from django.db import models
from django.contrib import admin
# Create your models here.
class BlogsPost(models.Model):
title = models.CharField(max_length = 150)
body = models.TextField()
timestamp = models.DateTimeField()
class BlogPostAdmin(admin.ModelAdmin): #ADD
list_display = ('title','timestamp') #ADD
admin.site.register(BlogsPost,BlogPostAdmin)
之后就可以看到后台可以展示博客的基本信息:
创建blog的公共部分###
从Django的角度看,一个页面具有三个典型的组件:
一个模板(template):模板负责把传递进来的信息显示出来。
一个视图(view):视图负责从数据库获取需要显示的信息。
一个URL模式:它负责把收到的请求和你的试图函数匹配,有时候也会向视图传递一些参数。
创建模板#####
在blog
项目下创建templates
目录(mysite/blog/templates/
),在目录下创建模板文件index.html
,内容如下:
{% for post in posts %}
{{ post.title }}
{{ post.timestamp }}
{{ post.body }}
{% endfor%}
创建视图函数
打开mysite/blog/views.py
文件:
#coding=utf-8
from django.shortcuts import render
from blog.models import BlogsPost
from django.shortcuts import render_to_response
# Create your views here.
def index(request):
blog_list = BlogsPost.objects.all()
return render_to_response('index.html',{'blog_list':blog_list})
创建blog的URL模式
在mysite/urls.py
文件里添加blog
的url
:
from django.conf.urls import include,url
from django.contrib import admin
import blog.views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^index/$', blog.views.index),
]
这里需要注意的是,由于Django 1.11
版本中不再支持url的字符串表示所以这里采用直接导入相应的文件
添加样式
创建基础模板,在mysite/blog/templates
目录里创建base.html
的模板:
My Blog
大人不华,君子务实
{% block content %}
{% endblock %}
修改index.html
模板,让它引用base.html
模板和它的content
块:
{% extends "base.html" %}
{% block content %}
{% for post in blog_list %}
{{ post.title }}
{{ post.timestamp | date:"1,F jS"}}
{{ post.body }}
{% endfor %}
{% endblock %}
再次刷新服务器,可以看到如下界面:
在建立好自己的博客之后,我对于
Django
的基本框架有了更加深入了解,相信在以后
SDUOJ
的开发中会更加得心应手