本文git地址:https://github.com/wangweiqq2010/django_demo.git
python框架
MVC和MTV
model(模型)、view(视图)和controller(控制器)
模型(Model)、模板(Template)和视图(Views)
Django模块安装
pip install django
Django项目创建
django-admin startproject django_demo
python manage.py startapp infomanage
Vue项目创建(Django项目目录下)
vue-init webpack frontend
使用Webpack打包Vue项目:
cd frontend
npm install
npm run build
至此,Vue项目创建完毕
Django配置文件(version:1a)
- 添加创建的app
# APPS的配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'infomanage', #此处为新创建的app
]
- Django项目的模板搜索路径配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['frontend/dist'], #此处为vue.js项目dist地址
'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',
],
},
},
]
]
- 静态文件地址配置
STATIC_URL = '/static/' # 默认已添加,使用静态文件时的前缀
# Add for vuejs
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "frontend/dist/static"),
]
- 数据库配置
# MySQL的配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname', #注意这里的数据库应该以utf-8编码
'USER': 'xxx',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '',
}
}
# 对于python3的使用者们还需要再加一步操作
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
# 如下设置放置的与project同名的配置的 __init__.py文件中
import pymysql
pymysql.install_as_MySQLdb()
Django路由系统(version:1b)
urlpatterns = [
url(正则表达式,view函数,参数,别名),
]
匹配顺序:从上到下
urlpatterns = [
# url匹配测试
url(r'^matchtest/2018/$', views.special_case_2018, name="special_case_2018"),
url(r'^matchtest/([0-9]{4})/$', views.year_archive, name="year_archive"),
url(r'^matchtest/([0-9]{4})/([0-9]{2})/$', views.month_archive, name="month_archive"),
]
def special_case_2018(request):
context = {'msg':'2018 : special_case_2018'}
return render(request, "infomanage/matchtest.html",context)
def year_archive(request, year):
context = {'msg': year + ' : year_archive'}
return render(request, "infomanage/matchtest.html", context)
def month_archive(request, year,month):
context = {'msg': year + '.'+ month + ' : month_archive'}
return render(request, "infomanage/matchtest.html", context)
- 正则表达式分组(?P
pattern)
urlpatterns = [
# 命名组测试
url(r'^group/(?P\d{4})/$', views.group_year_archive, name="group_year_archive"),
url(r'^group/(?P\d{4})/(?P\d{2})/$', views.group_month_archive, name="group_month_archive"),
]
def group_year_archive(request, year):
return render(request, "infomanage/group_year.html", locals())
def group_month_archive(request, year, month):
return render(request, "infomanage/group_month.html", locals())
- 二级路由 include
extra_patterns = [
url(r'^(?P\d{4})/$', views.group_year_archive, name="group_year_archive"),
url(r'^(?P\d{4})/(?P\d{2})/$', views.group_month_archive, name="group_month_archive"),
]
urlpatterns = [
# 二级路由测试
url(r'^group/', include(extra_patterns)),
]
#减少代码冗余
#原始版本
urlpatterns = [
url(r'^(?P[\w-]+)-(?P\w+)/history/$', views.history),
url(r'^(?P[\w-]+)-(?P\w+)/edit/$', views.edit),
url(r'^(?P[\w-]+)-(?P\w+)/discuss/$', views.discuss),
url(r'^(?P[\w-]+)-(?P\w+)/permissions/$', views.permissions),
]
#优化版本
urlpatterns = [
url(r'^(?P[\w-]+)-(?P\w+)/', include([
url(r'^history/$', views.history),
url(r'^edit/$', views.edit),
url(r'^discuss/$', views.discuss),
url(r'^permissions/$', views.permissions),
])),
]
- 额外参数
urlpatterns = [
# 额外参数测试
url(r'^extra_parameter/(?P\d{4})/$', views.extra_parameter, {"month": "06"}, name="extra_parameter"),
]
def extra_parameter(request, year, month):
return render(request, "infomanage/group_month.html", locals())
- 别名
urlpatterns = [
# 别名测试
url(r'^add_test/$', views.add_test, name="add_test"),
url(r'^add/(?P\d+)/(?P\d+)/$', views.add, name='add'),
# url(r'^new_add/(?P\d+)/(?P\d+)/$', views.add, name='new_add'),
url(r'^my_new_add/(?P\d+)/(?P\d+)/$', views.add, name='new_add'),
# 原有url仍可用
url(r'^new_add/(\d+)/(\d+)/$', views.old_add_redirect),
]
# 在views.py,models.py中的使用
from django.urls import reverse
def add(request, first, second):
add_result = int(first) + int(second)
msg = str(first) + "+" + str(second) + "=" + str(add_result)
return HttpResponse("" + msg + "")
def old_add_redirect(request, a, b):
return HttpResponseRedirect(
reverse('new_add', args=(a, b))
)
# 在templates中使用
# 不带参数的:
{% url 'name' %}
# 带参数的:参数可以是变量名
{% url 'name' 参数 %}
# 例子
计算4+5(旧)
计算4+5(新)
-指定View默认参数
# 指定view的默认配置
urlpatterns = [
url(r'group/$', views.group_year_archive, name="group_year_archive_null"),
url(r'^group/(?P\d{4})/$', views.group_year_archive, name="group_year_archive"),
]
def group_year_archive(request, year='2018'):
return render(request, "infomanage/group_year.html", locals())
视图函数 View
- HttpRequest对象
当请求一个页面时,Django 创建一个 HttpRequest对象包含原数据的请求。然后 Django 加载适当的视图,通过 HttpRequest作为视图函数的第一个参数。
path,method,GET,POST,COOKIES,FILES,user,session,META - HttpResponse对象
render(推荐),render_to_response, redirect
from django.shortcuts import render
import datetime
def my_view(request):
time = datetime.datetime.now()
#locals() 函数会以字典类型返回当前位置的全部局部变量
return render(request, 'myapp/index.html', locals())
模版 Templates
模型 Model(version:1c)
django遵循 Code Frist的原则,即:根据代码中定义的类来自动生成数据库表。
- 创建Model
字段和参数:参考1,参考2,参考3,示例:
class Human(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=50)
GENDER_CHOICE = ((u'M', u'Male'), (u'F', u'Female'),)
gender = models.CharField(max_length=2, choices=GENDER_CHOICE, null=True)
class Meta:
abstract = True
class Teacher(Human):
course = models.CharField(max_length=100)
age = models.IntegerField(max_length=3)
join_date = models.DateField()
email = models.EmailField()
introduction = models.TextField()
class Meta:
db_table = 'teacher'
get_latest_by = 'join_date'
class Student(Human):
grade = models.IntegerField(max_length=1)
s_class = models.CharField(max_length=50)
math = models.IntegerField(max_length=3)
class Meta:
db_table = 'student'
class Math(models.Model):
student = models.CharField(max_length=50)
score = models.IntegerField(max_length=3)
teacher = models.CharField(max_length=50)
date = models.DateField()
class Meta:
db_table = 'math'
ordering = ['-score']
- 建立Table
# 生成迁移,将迁移记录在migrations下生成:
python manage.py makemigrations [appname]
# 执行迁移,新建、更新数据库table:
python manage.py migrate [appname]
Django 模型类的Meta是一个内部类,它用于定义一些Django模型类的行为特性。详情:python django模型内部类meta详细解释
- 增删改查
def search_test(request):
# 查询所有
student = models.Student.objects.all()
for s in student:
print s.name + " " + str(s.math)
print "-"*20
# 获取单条数据,不存在则报错(不建议)
models.Student.objects.get(id=1)
# 获取指定条件的数据
models.Student.objects.filter(name='xiaoming')
# 将指定条件的数据更新
models.Student.objects.filter(name='xiaoming').update(gender='M')
models.Student.objects.filter(id__lt=3, id__gt=2) # 获取id大于2 且 小于3的值
models.Student.objects.filter(id__in=[1, 2, 3]) # 获取id等于1、2、3的数据
models.Student.objects.filter(name__contains="xiao")
models.Student.objects.filter(name__icontains="xiao") # icontains大小写不敏感
models.Student.objects.filter(name='seven').order_by('id') # asc
models.Student.objects.filter(name='seven').order_by('-id') # desc
# regex正则匹配,iregex 不区分大小写
models.Student.objects.get(name__regex=r'^(An?|The) +')
models.Student.objects.get(name__iregex=r'^(an?|the) +')
# date
#
models.Teacher.objects.filter(join_date__date=datetime.date(2005, 1, 1))
models.Teacher.objects.filter(join_date__date__gt=datetime.date(2005, 1, 1))
# year
#
models.Teacher.objects.filter(join_date__year=2005)
models.Teacher.objects.filter(join_date__year__gte=2005)
return redirect(reverse(viewname="model_test"))
Django Admin
创建管理员
python manage.py createsuperuser
修改app下admin.py文件
from django.contrib import admin
from .models import *
admin.site.register(Student)
显示界面增加名称:
class Student(Human):
grade = models.IntegerField()
s_class = models.CharField(max_length=50)
math = models.IntegerField(default=90)
class Meta:
db_table = 'student'
def __unicode__(self): # 在Python3中用 __str__ 代替 __unicode__
return self.name
后续:数据库怎么和model关联,django处理性能