• url路由、模板语言、ajax、用django框架创建表


    1、后台管理的左侧菜单,默认只有第一个页签下面的选项是显示的,点了别的页签再显示别的页签下面的选项,问题是:点了任何菜单的选项后,左侧菜单又成了第一个页签的选项显示,别的页签隐藏,也就是左侧的菜单刷新了一遍。

    2、登录页面,用户输入了用户名和密码,点了登录,如果输入的是错误的,则当前页面会刷新一遍(提交后就会刷新),用户已经输入的内容就全没有了;这需要用到ajax实现静默提交。

    3、登录网址是login.html,后台管理网址是index.html,如果用户不进入login.html而直接进入index.html的话,事实上用户就不用登录即可访问后台了;这需要用会话保持做限制(cookie、session),如果没有保存登录信息,输入index.html会自动跳转到login.html。

    1.路由系统

    1.1 简单描述

    django的每个url都对应一个python方法,

    ,比如用户输入的网址是127.0.0.1:8000/login,则django会默认从urls.py里配置的url,从上到下匹配,有匹配成功的,就执行对应方法,下面的就不匹配了;没有匹配的,就返回404。

    1.2 使用正则表达式配置url

    ,这些数字页签,每一个都对应一个url,比如有1000页,是不是也要在urls.py里写一千个路由记录?并不是,而是用正则表达式,见下,

    urls.py,

    # 使用正则表达式
    url(r'^detail/(d+)/' ,views.detail)

    views.py,

    # 如果urls.py里的url是两个值,比如/detail/123/那么对应的函数必须接收两个参数,如下,一个request,一个nid,不然会报错。
    def detail(request,nid):
        print(nid)
        return render(request,'back.html')

    根据取到的这个nid,就可以去数据库里取数据了,比如第一页取前十条数据,第二页取11条-20条数据。

    1.3 url设置关键参数

    urls.py,

    urlpatterns = [
        #url(r'^admin/', admin.site.urls),
        url(r'^index/$', views.index),
        url(r'^back/$', views.back),
        url(r'^check/$', views.check),
        url(r'^detail/(d+)/' ,views.detail),
    #设置关键参数,“?P<n1>”
        url(r'^detail1/(?P<n1>d+)/(?P<n2>d+)' ,views.detail1),
    ]

    views.py,

    #n1、n2是取的关键参数
    def detail1(request,n1,n2):
        print(n1,n2)
        return render(request,'back.html')

     2.实现分页展示和查看详情

    urls.py,

    urlpatterns = [
        url(r'^pageTest/(d+)/$', views.pageTest),
        url(r'^details/(d+)/$', views.details),
    ]

    views.py,

    from django.shortcuts import render
    from django.shortcuts import redirect
    from django.shortcuts import HttpResponse
    from cmdb import models
    # Create your views here.
    
    
    user_list1 = []
    for item in range(99):
        temp = {'id':str(item),'username':'zsc' + str(item),'email':'email' + str(item)}
        user_list1.append(temp)
    
    def pageTest(request,page):
        #1,0-9
        #2,10-19
        #3,20-29
    
        page = int(page)
        startpoint = (page - 1) * 10
        endpoint = page * 10
        user_list = user_list1[startpoint:endpoint]
        return render(request,'page.html',{'user_list':user_list})
    
    def details(request,nid):
        nid = int(nid)
        current_details = user_list1[nid]
        return render(request,'details.html',{'current_details':current_details})

    details.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <ul>
            <li>{{ current_details.id }}</li>
            <li>{{ current_details.username }}</li>
            <li>{{ current_details.email }}</li>
    
        </ul>
    </body>
    </html>

    page.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <table>
            <tr>
                <td>id</td>
                <td>username</td>
                <td>details</td>
            </tr>
    
            {% for item in user_list %}
                <tr>
                    <td>
                        {{ item.id }}
                    </td>
    
                    <td>
                        {{ item.username }}
                    </td>
                    <td>
                        <a href="/details/{{ item.id }}" target="_blank">see the details</a>
                    </td>
    
                </tr>
            {% endfor %}
        </table>
    </body>
    </html>

     

     3. 路由系统根据app分流

    一个项目有很多个app,比如web是主站,manger是后台,那urls.py怎么配置更合理呢?答案是根据app来实现url分流处理,见下以web为例配置的urls.py,

    项目里的urls.py,

    from django.conf.urls import url,include
    urlpatterns = [
    #以web开头的所有访问都抛给web这个app下面的urls.py
        url(r'^web/',include('web.urls.py')),
    
    ]

    在web这个app下面新建一个urls.py,

    from web import views
    
    urlpatterns = [
       url(r'^pageTest/(d+)/$', views.pageTest),
       url(r'^details/(d+)/$', views.details),     
    ]

    这样配置好后,比如访问127.0.0.1:8000/web/pageTest/1,就会将这个url抛给web下面的urls.py里对应的函数处理。

    这样,monitor的url交给monitor处理,manager的url交给manger处理,更清晰。

    4.模版语言之基本操作和filter

      ,如左面两个图所示,模板渲染的过程,其实就是把html转化为python方法的过程,在python方法里新建一个列表,然后把常量值都append进去,遇到变量值的话,再获取变量值然后append到列表里,最后将这些解析好的代码拼接成一个html页面,再return给用户。

    http://www.cnblogs.com/wupeiqi/articles/5237704.html

    4.1 基本操作

    urls.py,

    urlpatterns = [
        url(r'^templateTest/$', views.templateTest),
    ]

    templateTest.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <p>{{ k1 }}</p>
        <p>{{ k2 }}</p>
    #根据下标取列表的值时,不能用“[]”,必须用“.”
        <p>{{ k2.0 }}</p>
        {% for item in d1 %}
    # forloop.counter,从1开始依次输出;
    #  forloop.counter0,从0开始依次输出;
    #  forloop.first,判断是否是第一个值,如果是就返回true
            <p>{{ item }},{{ forloop.counter }},{{ forloop.counter0 }},{{ forloop.first }},{{ forloop.last }},{{ forloop.revcounter }}</p>
        {% endfor %}
    
        {% if k1 == 'v1' %}
            <h1>v1</h1>
            {% elif k1 == 'v2' %}
                <h1>v2</h1>
        {% else %}
            <h1>77777</h1>
        {% endif %}
    
    </body>
    </html>

    views.py,

    def templateTest(request):
        return render(request,'templateTest.html',{'k1':'v2','k2':[11,22,33],'d1':{'kk1':'vv1','kk2':'vv2','kk3':'vv3'}})

    4.2 模板内置方法

    {{ item.event_start|date:"Y-m-d H:i:s"}},将时间格式化输出
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }},将列表的第一个元素大写
    {{ name|lower }},将name的值小写。

    4.3 模板里自定义filter方法

    模板里内置的方法略显死板,所以还是有必要自己建模板方法的,步骤见下:

    1、在app(这里说的app意思是小程序,并不是名字叫app)目录下新建一个目录“templatetags”,目录名必须是这个,定死的;

    2、在templatetags目录下新建一个.py文件,比如说是tempTest.py,内容见下,

    #下面两行是必须导入的
    from django import template
    from django.utils.safestring import mark_safe
    
    #这里的register、template.Library()都是固定的,不能改名!!!
    register = template.Library()
    
    #加上下面这个装饰器后,这个python方法就变成了模板方法。
    #这个filter装饰器最多接收两个参数,第一个参数必须有,第二个参数可有可无;后面讲的simple_tag的装饰器支持多个参数。
    #如果想用filter处理多个参数怎么办?可以将多个字符串当成一个值传给函数,然后再做切片处理,如{{ k1 | f1:"zsc,aqq" }}
    @register.filter()
    def f1(v1,arg):
        return v1 + "666" + arg

    3、在html中引入模板方法,

        

    {% load tempTest %}
    #我们一般在第一行引入模板方法
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    #调用模板方法并传参数
        {{ k1|f1:"zsc" }}
    </body>
    </html>

    4、使用模板方法

    {{ k1|f1 }}
    #f1是tempTest.py里的方法

    5、在settings中配置当前app,不然django无法找到自定义的simple_tag

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    #此处app的名称是app01
        'app01',
    )

     5. 模版语言之simple_tag

    5.1 创建simple_tag模板语言

    from django import template
    from django.utils.safestring import mark_safe
    
    register = template.Library()
    
    @register.simple_tag
    def f2(s1,s2,s3,s4):
        return s1 + s2 + s3 + s4
    在html里调用方式:
    {% f2 "zsc" "1" "anqingqing" "xiaoxixi" %}

    5.2 filter和simple_tag对比

    filter:

      限制参数个数;

      支持作为模板语言if判断的条件,也就是可以用{% if k1|filterfunc %}这种形式,如果funcone返回true,就为真,返回false就为假。

    simple_tag:

      不限制参数个数;

      不支持作为模板语言if判断的条件,也就是不能用{% if simple_tag_func arg1 %}这种形式,不论simple_tag_func返回true或false都没作用。

    下例为html中的模板语言将filter作为if判断条件的例子:

    testTemp.py:
    
    from django import template
    from django.utils.safestring import mark_safe
    
    register = template.Library()
    @register.filter
    def f3(v1):
        if v1 == 'vvv':
            return True
        else:
            return False
    
    templateTest.py:
    {% if k1|f3 %}
    <h1>true</h1>
    {% else %}
    <h1>false</h1>
    {% endif %}

     6.模版语言之母板

    网站后台的格局一般是header、body、footer,body的左边是menu,右边是content,一般header和footer都是不变化的,点击menu里的选项后,比如点击“用户管理”,“用户管理”变成被选中的样式,同时右边的content区域出来用户的管理信息,点击“服务器管理”,“服务器管理”变成被选中的样式,同时右边的content区域出来服务器的管理信息。这其实是在“用户管理”和“服务器管理”上分别加了不同的url,跳转到不同的页面。这时候有个问题,跳转到不同的url,这俩html页面的header、footer都是不变化的,那用户管.html和服务器管理.html都要重新写一遍header和footer的内容吗?答案是否定的。这时候就要用到母板,创建一个母板,然后子html页面引用母板即可,就像导入python模块似的,见下例,

    urls.py,

    urlpatterns = [
        url(r'^motherModel/$', views.motherModel),
        url(r'^userinfo/$', views.userinfo),
        url(r'^serverinfo/$', views.serverinfo),
    
    ]

    views.py,

    def motherModel(request):
    
        return render(request,'motherModel.html')
    
    def userinfo(request):
        return render(request, 'userinfo.html', {'user_list': user_list1})
    
    def serverinfo(request):
        return render(request, 'serverinfo.html')

    motherModel.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <style>
            .page-header{
                100%;
                height:100px;
                background-color:red;
            }
    
            .page-body{
                min-height:400px;
            }
    
            .page-footer{
                100%;
                height:50px;
                background-color:green;
            }
            .menu{
                20%;
                float:left;
            }
    
            .content{
                80%;
                float:left;
            }
        </style>
    
    </head>
    <body>
        <div class="page-header">
    
        </div>
    
        <div class="page-body">
            <div class="menu">
                <ul>
                    <li><a href="/userinfo/">userManage</a></li>
                    <li><a href="/serverinfo/">serverManage</a></li>
                </ul>
    
            </div>
    
            <div class="content">
    #可以定义多个block,content是当前block的名称
                {% block content%}{%endblock%}
            </div>
        </div>
    
        <div class="page-footer">
    
        </div>
    </body>
    </html>

    userinfo.html,

    #导入母板html
    {% extends "motherModel.html" %}
    
    #这里也要写上{% block content %},与母板里的block对应
    {% block content %}
        <table>
            {% for item in user_list %}
                <li>{{ item.id }},{{ item.username }} ,{{ item.email }}</li>
            {% endfor %}
        </table>
    {% endblock %}

    serverinfo.html,

    {% extends "motherModel.html" %}
    
    {% block content %}
        <table>
            i am is a server,hello.
        </table>
    {% endblock %}

     7.模板导入js

    在上面的基础上,加了一个点击菜单后给菜单添加背景色效果。

    templateModel.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <style>
            .page-header{
                100%;
                height:100px;
                background-color:red;
            }
    
            .page-body{
                min-height:400px;
            }
    
            .page-footer{
                100%;
                height:50px;
                background-color:green;
            }
            .menu{
                20%;
                float:left;
            }
    
            .content{
                80%;
                float:left;
            }
    
            .activego{
                background-color:green;
            }
        </style>
    
    </head>
    <body>
        <div class="page-header">
    
        </div>
    
        <div class="page-body">
            <div class="menu">
                <ul>
                    <li><a id="userinfo" href="/userinfo/" class="usermanage">userManage</a></li>
                    <li><a id="serverinfo" href="/serverinfo/">serverManage</a></li>
                </ul>
    
            </div>
    
            <div class="content">
                {% block content %}{% endblock %}
            </div>
        </div>
    
        <div class="page-footer">
    
        </div>
    
    #此处导入一个js,使左侧菜单点击后添加背景
        {% block js %} {% endblock %}
    
    
    </body>
    </html>

    userinfo.html,

    {% extends "motherModel.html" %}
    
    {% block content %}
        <table>
            {% for item in user_list %}
                <li>{{ item.id }},{{ item.username }} ,{{ item.email }}</li>
            {% endfor %}
        </table>
    {% endblock %}
    
    
    {% block js %}
        <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $("#userinfo").addClass("activego")
        </script>
    {% endblock %}

    serverinfo.html,

    {% extends "motherModel.html" %}
    
    {% block content %}
        <table>
            i am is a server,hello.
        </table>
    {% endblock %}
    
    {% block js %}
        <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $("#serverinfo").addClass("activego")
        </script>
    {% endblock %}

     8.include小组件

    html页面有很多输入框、展示框,可以用引入的方式避免代码重复编写,见下,

    <body>
        <form>
            <input />
            <input />
            <input />
        </form>
    </body>
    
    等同于下面,
    <body>
        {% include 'x.html' %}
        {% include 'x.html' %}
        {% include 'x.html' %}
    </body>
    
    x.html,
    <form>
            <input />
            <input />
            <input />
        </form>

     9.Ajax使用(一)

    网站的注册登陆、网页版微信QQ,以及几乎所有的网站都在使用ajax,因为它可以做到不刷新页面就把数据提交到后台,让用户无感知。试想,如果网页版QQ,每发送一条信息都刷新一次网页,那闪瞎了该。

    正因为ajax的广泛使用及重要,所以有必要详细了解一下它。

    这里我们会基于jquery来使用ajax,因为jquery支持ajax支持的非常好。

    ajax示例

    urls.py,

    url(r'^ajaxTest/$', views.ajaxTest),

    ajaxTest.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div>
            <input type="text" value="username"  id="username" name="username"/>
        </div>
    
        <div>
            <input type="password" value="password"  id="password" name="password"/>
        </div>
    
        <div>
            <input type="button" value="submit"  id="submit" onclick="submitClick();" />
        </div>
    
        <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
        <script>
            function submitClick(){
                $.ajax({
    #form里的action的链接可以不带“/”,但是ajax里的url参数必须带“/”
                        url: "/ajaxTest/",
                        type: "POST",
    
    #将数据传给上面的url
                        data:{'username':$('#username').val(),'password':$('#password').val()},
    
    #data是上面的url的返回值
                        success:function(data){
                            if(data == '1') {
                               location.href = 'http://www.baidu.com';
                            }else{
                                alert('false');
                            }
                        }
                    }
                )
            }
        </script>
    </body>
    </html>

     9.Ajax使用(二)

    上面是根据返回的数值来判断是否合法,如果返回1就合法,返回2就不合法。事实上前端开发和后端开发是分开的,也就是事先必须约定好,到底1是合适,还是2是合法,还是0是合法,所以如果前端人员想改规则,则必须告诉后端人员,双方都需要改代码,所以最好是用json来通信,见下面代码,后端给前端返回一个包含状态和报错信息和的字典,然后前端取到状态,根据状态来决定做什么,

    ajaxTest.html,

    <script>
            function submitClick(){
                $.ajax({
                        url: "/ajaxTest/",
                        type: "POST",
                        data:{'username':$('#username').val(),'password':$('#password').val()},
                        success:function(data){
    #将收到的序列化字符串,反序列化成字典
                            var data = JSON.parse(data)
                            if(data.status) {
                                location.href = 'http://www.baidu.com';
                            }else{
                                alert(data.message);
                            }
                        }
                    }
                )
            }
        </script>

    views.py,

    import json
    def ajaxTest(request):
        if request.method == 'POST':
            ret = {'status':False,'message':''}
            username = request.POST.get("username",None)
            password = request.POST.get("password",None)
    
            if username=='111' and password=='222':
                ret['status'] = True
                return HttpResponse(json.dumps(ret))
            else:
                ret['message'] = 'invalid username or password.'
                return HttpResponse(json.dumps(ret))
        return render(request,'ajaxTest.html')

     10. ajax进阶

    jquery没有ajax功能,浏览器有一个模块是来实现ajax功能的,jquery是调用浏览器的这个模块,实现了ajax功能。浏览器包含一个XMLHttpRequest对象,正是用这个对象实现的ajax功能,jQuery通过调用XMLHttpRequest对象,封装了一些功能,让用户能简单的使用ajax。

    如果是跨域名提交ajax请求,浏览器会做拦截,自己的浏览器能发到对端的浏览器,对端的浏览器也能返回数据,但是返回来的数据会被自己的浏览器拦截。解决办法有两个:jsonp和修改浏览器设置,遇到了再说吧。

    11. Models创建数据库表

    from django.db import models
    
       
    class userinfo(models.Model):
        name = models.CharField(max_length=30)
        email = models.EmailField()
        memo = models.TextField()

    上面这个类就创建一个数据库表userinfo,name字段的数据类型是CharField,可以存储string类型数据;memo字段的数据类型是TextField;email字段的类型写的是EmailField,对数据库而言,没有EmailField这个数据类型,它也是存储string类型的数据,那为什么这里定义成EmailField呢,因为结合别的模块使用时会有特殊功能,比如结合admin.py(admin.py自带验证功能)来用,如果是EmailField类型的,admin.py会自动检测用户输入的内容是否符合邮箱格式。

    11.1 更多字段

    1、models.AutoField(primary_key=True)  自增列 = int(11)
      每个表默认会带一个自增id的字段,如果要显示的控制自增id字段,可以这样,
        class userinfo(models.Model):
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=30)
    
    2、models.CharField  字符串字段
      必须指定max_length 参数
    3、models.BooleanField  布尔类型=tinyint(1)
      不能为空,Blank=True
    4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
      继承CharField,所以必须指定max_lenght 参数。
        这个字段跟EmialField类似,对数据库而言就是一个存储string的字段而已,只是他要求用户输入的内容必须是以逗号分隔的数字,见下,
        11,223,32322。这样的数字是合法的,不然会提示不合法。
    5、models.DateField  日期类型 date
      对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
    6、models.DateTimeField  日期类型 datetime
      同DateField的参数
    7、models.Decimal  十进制小数类型 = decimal
      必须指定整数位max_digits和小数位decimal_places
    8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
      对字符串进行正则表达式
    9、models.FloatField  浮点类型 = double
    10、models.IntegerField  整形
    11、models.BigIntegerField  长整形
      integer_field_ranges = {
        'SmallIntegerField': (-32768, 32767),
        'IntegerField': (-2147483648, 2147483647),
        'BigIntegerField': (-9223372036854775808, 9223372036854775807),
        'PositiveSmallIntegerField': (0, 32767),
        'PositiveIntegerField': (0, 2147483647),
      }
    12、models.IPAddressField  字符串类型(ip4正则表达式);这个可能快过期了,在django1.10之后可能就不能用了,用下面的GenericIPAddressField代替。
    13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
      参数protocol可以是:both、ipv4、ipv6
      验证时,会根据设置报错
    14、models.NullBooleanField  允许为空的布尔类型
    15、models.PositiveIntegerFiel  正Integer
    16、models.PositiveSmallIntegerField  正smallInteger
    17、models.SlugField  减号、下划线、字母、数字
    18、models.SmallIntegerField  数字
      数据库中的字段有:tinyint、smallint、int、bigint
    19、models.TextField  字符串=longtext
    20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
    21、models.URLField  字符串,地址正则表达式;对数据库而言就是string,带有URL验证的功能。
    22、models.BinaryField  二进制
    23、models.ImageField   图片;对数据库而言就是个存储string的字段,对amdin.py而言,会生成一个带上传功能的框,默认上传到项目的根目录。
    24、models.FilePathField 文件;对数据库而言就是个存储string的字段,对amdin.py而言,会生成一个带上传功能的框

    11.2 创建表(一对多)并启用admin.py

    admin.py提供了很强大的后台管理功能,下面简单说一下,就能看出来它的方便和强大之处了。

    urls.py,

    url(r'^admin/', admin.site.urls),

    models.py,

    class UserType(models.Model):
        name = models.CharField(max_length=32)
    
    #这个方法是为了让admin页面显示出name的真实值,默认是显示object.name
        def __str__(self):
            return self.name
    
    class UserInfo(models.Model):
        user = models.CharField(max_length=32)
        passwd = models.CharField(max_length=32)
    
    #由于email和memo和user_type都是新加的字段,也就是说本来有user和passwd字段,只有这俩字段的时候做过一次python manage.py makemigrations,新增了字段再python manage.py makemigrations,就会提示一些东西,所以必须给新增的字段加上null=True,表示数据库允许该字段为空。
        email = models.EmailField(null=True)
        memo = models.TextField(null=True)
        # img = models.ImageField()
    
    #设置外键;blank=True是允许admin页面该项为空。
        user_type = models.ForeignKey("UserType",null=True,blank=True)
    
        def __str__(self):
            return self.user

    admin.py,

    from django.contrib import admin
    
    # Register your models here.
    
    from cmdb import models
    
    #将表注册到admin
    admin.site.register(models.UserInfo)
    admin.site.register(models.UserType)

    更新数据表和创建超级用户,

    python manage.py makemigrations
    python manage.py migrate
    
    #这个只需要执行一次,创建的是登录admin页面的管理员用户
    python manage.py createsuperuser

    userinfos 和user types就是我们创建的表,点击add就能添加了。

    11.3 创建表的多对多关系

    方法一:

    class Boy(models.Model):
        name = models.CharField(max_length=32)
    
        
    class Girl(models.Model):
        name = models.CharField(max_length=32)
        
    #加上这个后,就创建了Boy和Girl表的多对多关系。存储多对多关系的这个表是不可见的,名称就是Boy_Girl
        f = model.ManyToManyField(Boy)

    方法二:

    #主动创建一个表来存储多对多关系
    class B2G(models.Model):
        boy = models.ForeignKey('Boy')
        girl = models.ForeignKey('Girl')
    
    class Boy(models.Model):
        name = models.CharField(max_length=32)
    
        
    class Girl(models.Model):
        name = models.CharField(max_length=32)
        
        f = model.ManyToManyField(Boy)

    11.4 创建一对一关系表

    比如一个用户表,一个用户类型表,如果用户表里的user_type值设置为unique,那其实就实现了一对一的关系,比如用户张三的用户类型是超级用户,则不能再插入一个普通用户的张三。

    user_type = models.OneToOneField("UserType",null=True,blank=True)

    11.5 更多参数

    1、null=True,数据库中字段是否可以为空
    2、blank=True,django的Admin中添加数据时是否可允许空值
    3、primary_key=Flase,主键,对AutoField设置主键后,就会代替原来的自增id列
    4、auto_now=True,自动创建-----无论添加或修改,都是当前操作的时间;auto_now_add=True,自动创建-----永远是创建时得时间。
    5、chocies
    GENDER_CHOICE = {
        (0,'Male'),
        (1,'Female'),
    }
    gender = models.CharField(max_length=2,choices=GENDER_CHOICE,defalut=1)
    用户在页面上看到的性别是Male和Female,真是存储到数据库里的数据是0和1,这样就省去了性别和数字的联表操作。
    6、max_length
    7、defalut 默认值
    8、verbose_name Admin页面中字段的显示名称,比如name = CharField(max_length=32,verbose_name="用户名"),那admin页面就会显示用户名,而不是显示name。
    9、db_column,数据库中的列名;name = CharField(max_length=32)这一列的列名默认是name,如果name = CharField(max_length=32,db_column='n'),那么name这一列的列名就是n了。
    10、unique=True,不允许重复
    11、db_index=True,数据库索引
    12、editable=True,在Admin里是否可以编辑;如果设置为False,则这一项直接在admin页面上不显示了,还编辑个毛。
    13、error_messages=None,指定显示的错误信息,比如“用户名不能为空”。
    14、auto_created=False,自动创建
    15、help_text,在Admin中添加帮助信息
    16、validators=[],可以在里面放函数,比如放一个校验是否是合法手机号的函数,然后用户输入的内容就会根据这个函数去校验。
    17、upload_to,设置上传目录。img = models.ImageField(upload_to="upload")

     12.Model之基本数据操作

    利用双下划线将字段和对应的操作连接起来

    # 获取个数
        #
        # models.Tb1.objects.filter(name='seven').count()
    
        # 大于,小于
        #
        # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
        # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
    
        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
    
        # contains,这个就等同于mysql里的like,模糊查询
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")
    
        # range
        #
        # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
    
        # 其他类似
        #
        # startswith,istartswith, endswith, iendswith,
    
        # order by
        #
        # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
        # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
    
        # limit 、offset
        #
        # models.Tb1.objects.all()[10:20] #这就可以实现分页查询了。
    
        # group by
        from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))  #以values里的值进行groupby
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
        
    #如果想知道django里的数据库操作语句对应的mysql语句是什么,可以通过下面的方法。
    obj = models.Tb1.objects.filter(name='seven').count()
    print(obj.query)
        

     13.用ajax实现删除条目和编辑条目

    用ajax删除条目,后台数据库删除了数据,但是前端依然显示这一条记录,两个解决办法:

    1.点了删除后强制让页面刷新;

    2.点删除后,将这个条目的div移除($().remove()),然后替换成一个“删除成功”的div。

    编辑条目:

    1.点编辑后跳转到新的url;

    2.点编辑后弹出编辑框。

  • 相关阅读:
    题目1449:确定比赛名次
    题目1005:Graduate Admission
    HDU 4786 Fibonacci Tree
    FZU Problem 2136 取糖果
    iOS 递归锁
    iOS xcode问题集结
    iOS 芝麻认证开发(跳转本地的支付宝进行认证开发)
    iOS导出ipa包时四个选项的意义
    两排按钮循环
    Masony 常用方法
  • 原文地址:https://www.cnblogs.com/fuckily/p/6170605.html
Copyright © 2020-2023  润新知