Django+View.js学习笔记

本文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<name>pattern)
urlpatterns = [
    # 命名组测试
    url(r'^group/(?P<year>\d{4})/$', views.group_year_archive, name="group_year_archive"),
    url(r'^group/(?P<year>\d{4})/(?P<month>\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<year>\d{4})/$', views.group_year_archive, name="group_year_archive"),
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/$', views.group_month_archive, name="group_month_archive"),
]
urlpatterns = [
    # 二级路由测试
    url(r'^group/', include(extra_patterns)),
]
#减少代码冗余
#原始版本
urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$', views.history),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$', views.edit),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$', views.discuss),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]
#优化版本
urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\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<year>\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<first>\d+)/(?P<second>\d+)/$', views.add, name='add'),
    # url(r'^new_add/(?P<first>\d+)/(?P<second>\d+)/$', views.add, name='new_add'),
    url(r'^my_new_add/(?P<first>\d+)/(?P<second>\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("<h1>" + msg + "</h>")

def old_add_redirect(request, a, b):
    return HttpResponseRedirect(
        reverse('new_add', args=(a, b))
    )

# 在templates中使用
# 不带参数的:
{% url 'name' %}
# 带参数的:参数可以是变量名
{% url 'name' 参数 %}
# 例子
<a href="/infomanage/add/4/5">计算4+5(旧)</a>
<a href="{% url 'new_add' 4 5 %}">计算4+5(新)</a>

-指定View默认参数

# 指定view的默认配置
urlpatterns = [
    url(r'group/$', views.group_year_archive, name="group_year_archive_null"),
    url(r'^group/(?P<year>\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的原则,即:根据代码中定义的类来自动生成数据库表。

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处理性能

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容