首页 > 代码库 > Django【基础篇】

Django【基础篇】

一、视图和路由系统

    如果大家曾经发布过Hello,world页面,但是没有使用Web框架,只是简单的在hello.html文本中输入hello,world,然后上传到任意的一个网页服务器上。注意,这个过程中,说明了两个关于网页的关键信息:它包括(字符串"hello,world")和它的URL(http://www.example.com/hello.html)。

    使用Django来完成上面的步骤,需要用的知识:页面的内容是靠view function(视图函数)来产生,URL定义在URLconf中。下面,我们来通过Django来实现一个Hello,world的页面。

1,视图

    我们在创建项目的时候在mysite文件夹中,生成了一个名为views.py的文件,我们的Hello,World视图非常简单,这些是完整的函数和导入声明,代码如下:

1
2
3
4
form django.http import HttpResponse
 
def hello(request):
    return HttpResponse("Hello,World")

    首先我们需要导入HttpResponse模块,因为在Django在返回数据的时候需要一层封装,接下来,我们定义一个叫做hello的视图函数,每个视图函数至少有一个参数,通常被叫做request。这是一个触发这个视图、包含当前Web请求信息的对象,是类django.http.HttpRequest的一个实例。我们定义完了视图后,就需要让Django找到我们定义的这个视图函数。

2、路由系统

    现在,如果我们运行:python mangage.py runserver,还是看到的Django的欢迎界面,而看不到我们刚才写的Hello World显示页面。这是因为我们的mysite项目还对hello视图一无所知。我们需要通过一个详细描述的URL来显示告诉它并且激活这个视图,这里我们就用到了我们的路由系统。

    urls.py是我们在创建cmdb时生成的,这个文件就像是Django所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表。

1
2
3
4
5
6
7
8
from django.conf.urls import url
from django.contrib import admin
from cmdb import views
 
urlpatterns = [
    # url(r‘^admin/‘, admin.site.urls),
    url(r‘^hello/‘, views.hello),
]

    这里有一个问题值得声明一下,Django在检查URL模式前,移除每一个申请的URL开头的斜杠,这意味着我们为/hello/写URL模式不用包含斜杠,URL的模式包含了一个尖角号(^)和一个美元符号($),这些都是正则表达式符号,并且有特定的含义:上尖角要求表达式对字符串的头部进行匹配,美元符号则要求表达式对字符串的尾部进行匹配。

    如果你是喜欢所有URL都以‘/‘结尾的话,那么只需要在每个URL后添加斜杠,并且设置settings里的"APPEND_SLASH"为"True";如果不喜欢URL以斜杠结尾或者根据每个URL来决定,那么需要设置"APPEND_SLASH"为"False",并且根据你自己的意愿来添加结尾斜杠在URL模式后。

刚才我们也提到了在路由系统中可以使用正则表达式来进行匹配,下面我们就来举几个应用正则表达式的例子:

例一:每个路由规则对应一个view中的函数

1
2
3
4
5
6
7
8
9
10
url(r‘^index/(\d*)‘,views.index),
#匹配index/后面带数字的页面,如:index/1/,index/2/
  
 
url(r‘^manage/(?P<name>\w*)/(?P<id>\d*)‘,views.manage),
#匹配manage/所有字符赋值给name/所有数字赋值给id,这是正则表达式的分组
  
 
url(r‘^manage/(?P<id>\d+/$)‘,views.manage,{‘id‘:333}),
#这里,正则表达式和额外字典都包含了一个id。额外字典的id将优先使用,就是说任何请求都会作id设置为333对待,不管URl里面捕捉到什么样的值。
 

同时也要修改views的配置:

1
2
3
4
5
6
7
8
9
10
def login(request):    
    return HttpResponse(‘Ok‘)
 
def detail(request,nid):
    print(nid)
    return HttpResponse(‘Ok‘)
 
def detail2(request,nid,nnid):
    print(nid,nnid)
    return HttpResponse(‘Ok‘)

例二:根据app对路由规则进行一次分类

1
2
3
url(r‘^web/‘,include(‘web.urls‘)),
 
#每当Django遇到include()时,不再是当前的url来处理了,而是将请求发送到web app里自定义的urls进行处理(路由分发)。

    Dajngo中的路由系统和其他语言的框架有所不同,在Django中每一个请求的URL都要有一条路由映射,这样才能将请求交给一个views中的函数去处理。其他大部分的Web框架则是一类的url请求做一条路由映射,从而使路由系统变得简洁,如果想让页面跳转到自定义页面return redirect(自定义界面)

例三:利用反射机制,为Django开发一套动态路由系统

配置urls.py路由映射:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.conf.urls import patterns, include, url
from django.contrib import admin
from DynamicRouter.activator import process
 
urlpatterns = patterns(‘‘,
    # Examples:
    # url(r‘^$‘, ‘DynamicRouter.views.home‘, name=‘home‘),
    # url(r‘^blog/‘, include(‘blog.urls‘)),
 
    url(r‘^admin/‘, include(admin.site.urls)),
     
     
    (‘^(?P<app>(\w+))/(?P<function>(\w+))/(?P<page>(\d+))/(?P<id>(\d+))/$‘,process),
    (‘^(?P<app>(\w+))/(?P<function>(\w+))/(?P<id>(\d+))/$‘,process),
    (‘^(?P<app>(\w+))/(?P<function>(\w+))/$‘,process),
    (‘^(?P<app>(\w+))/$‘,process,{‘function‘:‘index‘}),
)

根据urls.py中获取的参数,通过反射调用指定app/views.py中的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python
#coding:utf-8
 
from django.shortcuts import render_to_response,HttpResponse,redirect
 
 
def process(request,**kwargs):
    ‘‘‘接收所有匹配url的请求,根据请求url中的参数,通过反射动态指定view中的方法‘‘‘
     
    app =  kwargs.get(‘app‘,None)
    function = kwargs.get(‘function‘,None)
     
    try:
        appObj = __import__("%s.views" %app)
        viewObj = getattr(appObj, ‘views‘)
        funcObj = getattr(viewObj, function)
         
        #执行view.py中的函数,并获取其返回值
        result = funcObj(request,kwargs)
         
    except (ImportError,AttributeError),e:
        #导入失败时,自定义404错误
        return HttpResponse(‘404 Not Found‘)
    except Exception,e:
        #代码执行异常时,自动跳转到指定页面
        return redirect(‘/app01/index/‘)
     
    return result

执行方法:

1
2
3
4
5
http://127.0.0.1:9000/app01/index/  ==》 执行app01/view.py文件中的index函数
 
http://127.0.0.1:9000/app02/index/  ==》 执行app02/view.py文件中的index函数
 
http://127.0.0.1:9000/app01/login/  ==》 执行app01/view.py文件中的login函数

例四:实现网页分页显示

urls.py配置:

1
2
3
4
5
6
from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r‘^index/(\d+)‘, views.index),

views.py配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from django.shortcuts import render
  
from django.shortcuts import HttpResponse
  
USER_LIST = []         #制造一些数据
for item in range(94):
    temp = {‘id‘:item,‘user‘:‘haifeng‘ + str(item),‘email‘:‘email‘ + str(item)}
    USER_LIST.append(temp)
  
def index(request,page):
    """
  
    :param request:
    :param page:进行数据分页显示
    :return:
    """
    page = int(page)
    start = (page - 1) * 10
    end = page * 10
    user_list = USER_LIST[start:end]
    return render(request,‘index.html‘,{‘user_list‘:user_list})

访问效果:

技术分享

例五:根据用户输入的ID号查找出ID详细信息

urls.py配置:

1
2
3
4
5
6
7
from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^detail/(\d+)‘, views.detail),

views.py配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from django.shortcuts import render
 
# Create your views here.
 
from django.shortcuts import HttpResponse
 
USER_LIST = []
for item in range(94):
    temp = {‘id‘:item,‘user‘:‘haifeng‘ + str(item),‘email‘:‘email‘ + str(item)}
    USER_LIST.append(temp)
 
def detail(request,nid):
    """
 
    :param request:
    :param nid:根据数据的ID查找出对应ID的所有信息
    :return:
    """
    nid = int(nid)
    current_detail_dict = USER_LIST[nid]
    return render(request,‘detail.html‘,{‘current_detail_dict‘:current_detail_dict})

detail.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>detail</title>
</head>
<body>
    <ul>
        <li>
            {{ current_detail_dict.id }}
        </li>
        <li>
            {{ current_detail_dict.user }}
        </li>
        <li>
            {{ current_detail_dict.email }}
        </li>
    </ul>
 
</body>
</html>

访问效果:

技术分享

二、模板

    模板是一个文本,用于分离文档的表现形式和内容。模板定义了占位符以及各种用语言规范文档该如何显示的各部分基本逻辑(模板标签)。模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档。

1、模板语言

模板中也有自己的语言,该语言可以实现数据展示,下面我们根据这个views.py来具体介绍一下模板语言:

1
2
3
4
5
6
7
8
9
def template(request):
    """
    自定义方法,filter,simple_tag
    :param request:
    :return:
    """
    return render(request,
                  ‘template.html‘,
                  {‘k1‘:‘vvv‘,‘k2‘:[11,22,33],‘k3‘:{‘nid‘:12,‘name‘:‘jack‘}})
  • {{ k1 }}:定义变量,结果:vvv;

  • {{ k1.0 }}:索引位置为0的字符,结果:v;

  • {{ k1.name }}:获取字典里name的值,结果:jack;

  • for循环

1
2
3
4
5
6
7
8
9
10
11
{% for item in k2 %}        #循环k2这个列表
    <p>{{ item }}</p>       #获取所有值,11,22,33
 
    <p>{{ forloop.counter }}</p>       #获取索引位置,但这个索引位置从1开始
    <p>{{ forloop.counter0 }}</p>      #获取索引位置,但将初始索引位置至为0
 
    <p>{{ forloop.first }},{{ forloop.last }}</p> #判断是否是第一个或最后一个,返回结果为:True or False
 
    <p>{{ forloop.revcounter }}</p>    #倒排索引,从1开始
 
{% endfor }
  • {% if ordered_warranty %},{% else %},{ % endif % }

  • 母板:{% block title %},{% endblock %}

  • 子板:{% extends "base.html" %},{% block title %},{% endblock %}

例:模板继承,减少公用页面区域所引起的重复和冗余代码

urls.py定义路由规则:

1
2
3
4
5
6
7
8
from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^assets/‘, views.assets),
    url(r‘^userinfo/‘, views.userinfo),

views.py定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.shortcuts import render
 
# Create your views here.
 
from django.shortcuts import HttpResponse
 
def assets(request):
    assets_list = []
    for i in range(10):
        temp = {‘hostname‘:‘host‘+ str(i),‘port‘:80}
        assets_list.append(temp)
    return render(request,‘assets.html‘,{‘assets_list‘:assets_list})
 
def userinfo(request):
    user_list = []
    for i in range(10):
        temp = {‘username‘: ‘user‘ + str(i), ‘pwd‘: ‘123‘ + str(i) }
        user_list.append(temp)
    return render(request,‘userinfo.html‘,{"user_list":user_list})

定义母板,layout.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="..." />
    <style>
        .pg-header{
            height: 48px;
            background-color: cadetblue;
        }
        .pg-body{
            min-height: 500px;
        }
        .pg-body .body-menu{
            width: 20%;
            float: left;
        }
        .pg-body .body-content{
            width: 80%;
            float: left;
        }
        .pg-footer{
            height: 100px;
            background-color: brown;
        }
        .active{
            background-color: aquamarine;
            color: white;
        }
    </style>
 
    {% block css %}{% endblock %}
</head>
<body>
    <div class="pg-header" style="font-size: 40px">
        后台系统V1.0
    </div>
    <div class="pg-body">
        <div class="body-menu">
            <ul>
                <li><a id="userinfo" href="/userinfo">用户管理</a></li>
                <li><a id="assets" href="/assets">资产管理</a></li>
            </ul>
        </div>
        <div class="body-content">
            {% block body %}{% endblock %}  
        </div>
 
    </div>
    <div class="pg-footer"></div>
    <script src="xxx"></script>
    {% block js %}{% endblock %}
</body>
</html>

定义各个子板来继承母板:

assets.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{% extends ‘layout.html‘ %}
 
 
{% block body %}
    <table>
        {% for item in assets_list %}
            <tr>
                <td>{{ item.hostname }}</td>
                <td>{{ item.port }}</td>
            </tr>
        {% endfor %}
    </table>
{% endblock %}
{% block js %}
    <script>
        document.getElementById(‘assets‘).className = ‘active‘;
    </script>
{% endblock %}

userinfo.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{% extends ‘layout.html‘ %}
 
{% block css %}
    <style></style>
{% endblock %}
 
{% block body %}
    <ul>
    {% for item in user_list %}
        <li>{{ item.username }},{{ item.salary }}</li>
    {% endfor %}
    </ul>
 
{% endblock %}
 
{% block js %}
    <script>
        document.getElementById(‘userinfo‘).className = ‘active‘;
    </script>
{% endblock %}

访问效果:

技术分享

2、自定义模板方法

自定义的模板方法分为两种:

  • filter:有传参的限制,支持模板语言的if条件;

  • simple_tag:不支持模板语言的if条件。

定义模板方法的步骤:

  • 在app中创建templatetags模块;

  • 创建任意文件.py文件,如:xx.py;

定义?xx.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python
 
from django import template
from django.utils.safestring import mark_safe
# from django.template.base import Node, TemplateSyntaxError
 
# 必须不变register
register = template.Library()
 
@register.filter
def f1(value,arg):
    return value + "666" + arg
 
@register.simple_tag
def f2(s1,s2,s3,s4):
    return s1 + s2 + s3 + s4
 
@register.filter
def f3(value):
    if value == ‘VVV‘:
        return True
    return False
  • 在使用自定义simple_tag的HTML文件中导入之前创建的xx.py文件名:{% load xx  %}

  • 使用simple_tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#两种方法:
 
{% my_simple_time 1 2 3 %}
 
{% my_input ‘id_username‘ ‘hide‘%}
 
#例子:(结合我们之前的例子,修改template.html)
{{ k1|f1:"jack" }}
 
{% f2 1 2 3 4 %}
 
{% if k1|f3 %}
    <h1>True</h1>
{% else %}
    <h1>False</h1>
{% endif %}
  • 在settings中配置当前的app,不然django无法找到自定义的simple_tag:

1
2
3
4
5
6
7
8
9
INSTALLED_APPS = (
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘app01‘,
)

3、include模板标签

   该标签允许在(模板中)包含其它的模板的内容。标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。每当在多个模板中出现相同的代码时,就应该考虑是否使用{% include %}来减少重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# mypage.html
 
<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>
 
# includes/nav.html
 
<div id="nav">
    You are in: {{ current_section }}
</div>

如何将一个HTML转换成一个函数:

技术分享

三、Ajax

1,Ajax分类:

  • XMLHttpRequest对象(原生Ajax);

  • jQuery - XMLHttpRequest对象(jQuery ajax);

  • 跨域Ajax:在跨域Ajax中要注意浏览器的同源策略,Ajax只能给自己的域名发请求;跨域名,浏览器做了拦截。

2,利用AJAX可以做什么

  • 注册时,输入用户名自动检测用户是否已经存在;

  • 登录时,提示用户名密码错误;

  • 删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据也删除。

3、jQuery Ajax

    jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发组可以在基础上写更少的代码实现更多的功能。

 

下面通过一个Ajax的例子来介绍其使用方法:

定义路由规则:urls.py

1
2
3
4
5
6
7
8
from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^ajax_demo/‘, views.ajax_demo),
]

定义视图:views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.shortcuts import render
from django.shortcuts import HttpResponse
import json
 
def ajax_demo(request):
    if request.method == ‘POST‘:
        ret = {‘status‘:False,‘message‘:‘‘}
        user = request.POST.get(‘user‘,None)
        pwd = request.POST.get(‘pwd‘,None)
        if user == ‘jack‘ and pwd == ‘123‘:
            ret[‘status‘] = True
            return HttpResponse(json.dumps(ret))
        else:
            ret[‘message‘] = "用户名或密码错误!!"
            return HttpResponse(json.dumps(ret))
    return render(request,‘ajax_demo.html‘)

定义HTML:ajax_demo.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <p>用户名:<input type="text" id="username"/></p>
    </div>
    <div>
        <p>密码:<input type="password" id="pwd"/></p>
    </div>
    <input type="button" value=http://www.mamicode.com/"提交" onclick="SubmitForm();"/>
    <script src=http://www.mamicode.com/"/static/jquery-1.12.4.js"></script>
    <script>
        function SubmitForm() {
            $.ajax({
                url:‘/ajax_demo/‘,
                //url前后必须加上/
                type:‘POST‘,
                data:{‘user‘:$(‘#username‘).val(),‘pwd‘:$(‘#pwd‘).val()},
                dataType:‘json‘,
                success:function (data) {
                    //data为对象
                    //var data_dict = JSON.parse(data);  dataType在jQuery已经做了将json字符串转换成对象
                    if(data.status){
                        location.href = http://www.mamicode.com/‘http://www.baidu.com‘;
                    }else{
                        alert(data.message);
                    }
                }
            })
        }
    </script>
</body>

访问效果:

    当我们输入正确会自动跳转到百度的界面,如果输入错误触发alert弹框,报错:用户名密码错误。

四、Model模型(数据库相关操作)

 1、创建数据库

  1、创建model类,在APP的models.py文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.db import models
 
# Create your models here.
 
class userinfo(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    memo = models.TextField()
    # img = models.ImageField()
    user_type = models.ForeignKey("UserType",null=True,blank=True)
    #"UserType加双引号,UserType这个表可以放下面,不加双引号必须放上面"
 
class UserType(models.Model):
    name = models.CharField(max_length=32)
 
    def __str__(self):
        return self.name
技术分享
#models.AutoField  自增列 = int(11)#如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。 #models.CharField  字符串字段#必须 max_length 参数 #models.BooleanField  布尔类型=tinyint(1)#不能为空,Blank=True #models.ComaSeparatedIntegerField  用逗号分割的数字=varchar#继承CharField,所以必须 max_lenght 参数 #models.DateField  日期类型 date#对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。 #models.DateTimeField  日期类型 datetime#同DateField的参数 #models.Decimal  十进制小数类型 = decimal#必须指定整数位max_digits和小数位decimal_places #models.EmailField  字符串类型(正则表达式邮箱) =varchar#对字符串进行正则表达式 #models.FloatField  浮点类型 = double#models.IntegerField  整形#models.BigIntegerField  长整形#integer_field_ranges = {#    ‘SmallIntegerField‘: (-32768, 32767),#    ‘IntegerField‘: (-2147483648, 2147483647),#    ‘BigIntegerField‘: (-9223372036854775808, 9223372036854775807),#    ‘PositiveSmallIntegerField‘: (0, 32767),#    ‘PositiveIntegerField‘: (0, 2147483647),#  }  #models.IPAddressField  字符串类型(ip4正则表达式) #models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)#参数protocol可以是:both、ipv4、ipv6#验证时,会根据设置报错 #models.NullBooleanField  允许为空的布尔类型 #models.PositiveIntegerFiel  正Integer #models.PositiveSmallIntegerField  正smallInteger #models.SlugField  减号、下划线、字母、数字 #models.SmallIntegerField  数字#数据库中的字段有:tinyint、smallint、int、bigint #models.TextField  字符串=longtext #models.TimeField  时间 HH:MM[:ss[.uuuuuu]] #models.URLField  字符串,地址正则表达式 #models.BinaryField  二进制 #models.ImageField   图片 #models.FilePathField 文件
更多字段
 
技术分享
#null=True:数据库中字段是否可以为空 #blank=True:django的 Admin 中添加数据时是否可允许空值 #primary_key = False:主键,对AutoField设置主键后,就会代替原来的自增 id 列 #auto_now 和 auto_now_add#auto_now   自动创建---无论添加或修改,都是当前操作的时间#auto_now_add  自动创建---永远是创建时的时间 #choices#GENDER_CHOICE = (#        (u‘M‘, u‘Male‘),#        (u‘F‘, u‘Female‘),#    )#gender = models.CharField(max_length=2,choices = GENDER_CHOICE) #max_length#default:默认值#verbose_name:Admin中字段的显示名称#name|db_column:数据库中的字段名称#unique=True:不允许重复#db_index = True:数据库索引#editable=True:在Admin里是否可编辑#error_messages=None:错误提示#auto_created=False:自动创建#help_text:在Admin中提示帮助信息#validators=[]#upload-to
更多参数

2、注册APP,修改setting文件;

3、执行创建数据库命令:

1
2
3
python  manage.py makemigrations
 
python  manage.py migrate

4、如果我们使用Django自带的admin管理界面就应当先创建超级用户,命令如下:

1
python manage.py createsuperuser

5、配置admin.py来配置后台管理

1
2
3
4
5
6
7
8
from django.contrib import admin
 
# Register your models here.
 
from app01 import models
 
admin.site.register(models.userinfo)
admin.site.register(models.UserType)

6、访问:http://127.0.0.1:8080/admin 登录后可以看到我们创建的数据库。

技术分享

2、连表关系

  • 一对多:models.ForeignKey(ColorDic);

  • 一对一:models.OneToOneField(OneModel);

  • 多对多:authors = models.ManyToManyField(Author)

 
1
2
3
4
5
6
7
8
9
10
11
12
13
#应用场景#
  
#一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了)。
  
#例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表在添加5列数据。
 
#一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)。
  
#例如:创建用户信息时,需要选择一个用户类型【普通用户】【超级用户】等
  
#多对多:在某表中创建一行数据时,有一个可以多选的下拉框。
  
#例如:创建用户信息,需要为用户指定多个爱好。

3、数据库操作

    Django对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。Django为这些数据库提供了统一的调用API。我们可以根据自己业务需求选择不同的数据库,下面主要操作我们常用的MySQL数据库。

1、数据库配置,修改settings.py文件

1
2
3
4
5
6
7
8
9
10
DATABASES = {
    ‘default‘: {
        ‘ENGINE‘: ‘django.db.backends.mysql‘,
        ‘NAME‘: ‘test‘,
        ‘USER‘: ‘test‘,
        ‘PASSWORD‘: ‘test123‘,
        ‘HOST‘:‘localhost‘,
        ‘PORT‘:‘3306‘,
    }
}

2、操作数据库

增加数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
class userinfo(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    memo = models.TextField()
    # img = models.ImageField()
    user_type = models.ForeignKey("UserType",null=True,blank=True)
    #"UserType加双引号,UserType这个表可以放下面,不加双引号必须放上面"
 
class UserType(models.Model):
    name = models.CharField(max_length=32)
 
    def __str__(self):
        return self.name
1
2
3
4
5
6
from app01.models import userinfo
 
def index(request):
    test1 = userinfo(name=‘haifeng18‘,email=‘haifeng18@qq.com‘,memo=‘123123‘)
    test1.save()
    return HttpResponse("<p>数据添加成功!</p>")

获取数据,我们可以通过 print(obj.query)打印SQL语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from app01.models import userinfo
from app01.models import UserType
 
def index(request):
    # 初始化
    response = ""
    response1 = ""
 
    # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
    data_list = userinfo.objects.all()
 
    # # filter相当于SQL中的WHERE,可设置条件过滤结果
    # response2 = userinfo.objects.filter(name="haifeng18")
    #
    # # 获取单个对象
    # response3 = userinfo.objects.get(id=1)
 
    #
    # # 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;
    # # userinfo.objects.order_by(‘name‘)[0:2]
    #
    # # 数据排序
    # userinfo.objects.order_by("id")
    #
    # # 上面的方法可以连锁使用
    # userinfo.objects.filter(name="haifeng18").order_by("id")
 
    # 输出所有数据
    for var in data_list:
        response1 += var.name + " " + var.email
    response = response1
    return HttpResponse("<p>" + response  + "</p>")

更新数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from app01.models import userinfo
from app01.models import UserType
 
def index(request):
    # 修改其中一个name=“haifeng18”的字段,再save,相当于SQL中的UPDATE
    # test1 = userinfo.objects.get(name="haifeng18")
    # test1.name = ‘haifeng‘
    # test1.save()
 
    # 另外一种方式
    # userinfo.objects.filter(name="haifeng").update(name=‘haifeng123‘)
 
    # 修改所有的列
    userinfo.objects.all().update(name=‘haifeng18‘)
 
    return HttpResponse("<p>修改成功</p>")

删除数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from app01.models import userinfo
from app01.models import UserType
 
def index(request):
    # 删除name="haifeng18"的数据
    # test1 = userinfo.objects.get(name="haifeng18")
    # test1.delete()
 
    # 另外一种方式
    userinfo.objects.filter(name="haifeng18").delete()
 
    # 删除所有数据
    # userinfo.objects.all().delete()
 
    return HttpResponse("<p>删除成功</p>")

    今天的内容就到这里,想了解更多内容请参考下篇Django【进阶篇】。

相关参考网站:

  • python的re模块

  • ?Django book 3.0

  • ??Django book 2.0

  • ??SQLAlchemy基础教程



Django【基础篇】