创建App blog
- 在创建的工程的目录下执行
manage.py startapp blog
- 查看app目录下生成的文件
>tree /F
...
│ admin.py
│ apps.py
│ models.py
│ tests.py
│ views.py
│ __init__.py
│
└─migrations
__init__.py
文件名 | 描述/用途 |
---|---|
admin.py | |
apps.py | |
models.py | 数据模型 |
tests.py | 单元测试 |
views.py | 视图函数 |
_init_.py | 告诉python这是一个包 |
migrations\__init__.py | 告诉python这是一个包 |
- 将应用名加入到settings.py中的INSTALLED_APPS
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog'
]
- 编辑
models.py
, 添加BlogPost类
# Create your models here.
class BlogPost(models.Model):
title = models.CharField(max_lenth=150)
body = models.TextField()
timestamp = models.DataTimeField()
- 更多自动类型参考https://docs.djangoproject.com/en/2.2/ref/models/fields/#
- 可以使用
manage.py check
命令检查语法错误
- settings.py中设置数据库,默认就是sqlite, 无需修改
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
- Django1.7版本开始,移除了syncdb命令,同步(迁移)数据库用如下两个命令:
#在APP的migrations文件下生成*.py记录models.py的改动,文件名从0001开始
manage.py makemigrations
#把改动应用到数据库,如创建表,增加字段等
manage.py migrate
如果想只更新单个APP,在命名后面知道AP名字
manage.py makemigrations blog
manage.py migrate blog
生成的0001_initial.py
# -*- coding: utf-8 -*-
# Generated by Django 1.11.16 on xxxx
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='BlogPost',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=150)),
('body', models.TextField()),
('timestamp', models.DateTimeField()),
],
),
]
测试数据模型
Django提供了Python应用Shell,通过这个应用,可以实例化模型,并与应用交互
- 启动shell
>manage.py shell
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
- 测试数据模型
>>> from datetime import datetime
>>> from blog.models import BlogPost
>>> BlogPost.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python27\lib\site-packages\django-1.11.16-py2.7.egg\django\db\models\
query.py", line 226, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "C:\Python27\lib\site-packages\django-1.11.16-py2.7.egg\django\db\models\
query.py", line 250, in __iter__
self._fetch_all()
File "C:\Python27\lib\site-packages\django-1.11.16-py2.7.egg\django\db\models\
query.py", line 1121, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Python27\lib\site-packages\django-1.11.16-py2.7.egg\django\db\models\
query.py", line 53, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
File "C:\Python27\lib\site-packages\django-1.11.16-py2.7.egg\django\db\models\
sql\compiler.py", line 899, in execute_sql
raise original_exception
OperationalError: no such table: blog_blogpost
>>> BlogPost.objects.all()
<QuerySet []>
>>> bp = BlogPost(title='blog title', body='blog body',timestamp=datetime.now())
>>> bp
<BlogPost: BlogPost object>
>>> bp.save()
C:\Python27\lib\site-packages\django-1.11.16-py2.7.egg\django\db\models\fields\_
_init__.py:1451: RuntimeWarning: DateTimeField BlogPost.timestamp received a nai
ve datetime (2019-05-07 09:54:17.990000) while time zone support is active.
RuntimeWarning)
>>> BlogPost.objects.count()
1
>>> BlogPost.objects.all()
<QuerySet [<BlogPost: BlogPost object>]>
>>> BlogPost.objects.all()[0]
<BlogPost: BlogPost object>
>>> print bp.title
blog title
>>> print bp.body
blog body
>>> print bp.timestamp
2019-05-07 09:54:17.990000
Django管理应用
Django的admin服务已经默认开启
添加要管理的模型
在blog\admin.py中添加
from blog import models
# Register your models here.
admin.site.register(models.BlogPost)
创建超级用户
执行命令创建超级用户,按提示输入信息,密码长度最少8个字符。
manage.py createsuperuser
使用admin
- 启动服务
manage.py runserver
- 浏览器访问http://127.0.0.1:8000/admin
- 输入用户名密码登录
- 添加新blog
此时列表显示的都是BlogPost对象,无法区分内容 - 增加显示的内容
修改blog\admin.py
#新增类,定制显示的内容
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'timestamp')
admin.site.register(models.BlogPost, BlogPostAdmin)
刷新页面即可看到变化
创建博客的用户界面
从Django角度,web页面应该有以下几个经典组件
- 一个模板, 用于显示通过Python类字典对象传入的信息
- 一个视图函数,用于执行针对请求的核心逻辑。视图会从数据库中获取信息,并格式化显示结果。
- 一个URL模式,将传入的请求映射到对应的视图中,同时也可以将参数传递给视图。
创建模板
新建blog\templates\archive.html, 模板名可以随便起,模板目录名必须为templates。
<!-- archive.html -->
{% for post in posts %}
<h2>{{post.title}}</h2>
<p>{{post.timestamp}}</p>
<p>{{post.body}}</p>
{% endfor %}
关于模板和标签更多信息,参考https://docs.djangoproject.com/en/2.2/ref/templates/language/
创建URL模式
- 修改
urls.py
from django.conf.urls import url, include #添加include
from django.contrib import admin
urlpatterns = [
url(r'^blog/', include('blog.urls')), #新增
url(r'^admin/', admin.site.urls),
]
- 新建
blog/urls.py
#urls.py
from django.con.urls.defaults import *
urlpatterns = patterns('blog.views'
url(r'^$', archive), #对应blog/views.py中的archive()
#url(r'foo/', foo), #还没有定义
#url(r'bar/', bar), #还没有定义
)
创建视图
在blog\views.py
中添加
from datetime import datetime
from blog.models import BlogPost
# Create your views here.
def archive(request):
# 创建一个假的blog
post = BlogPost(title='mocktitle', body='mockbody', timestamp=datetime.now())
return render(request, 'archive.html',{'posts':[post]}) #Django1.3后新增render()方法,比render_to_response()更便捷。
浏览器查看
访问http://127.0.0.1:8000/blog
debug页面,chrome可以在页面任意位置右键选择Inspect
使用真实视图
修改blog/views.py
def archive(request):
posts = BlogPost.objects.all() #从数据库中获取
return render(request, 'archive.html',{'posts':posts})