zoukankan      html  css  js  c++  java
  • Django web 进阶

    1、路由系统
    
    2、模板引擎
    
        simple_tag
    
    3、Form
    
    4、Ajax请求
    
        -简单数据
    
        -复杂数据
    
     
    
    内容:
        -作业
    
        model
    
        xss、csrf(安全方面的内容)
    
        分页(公共的模块)
    内容复习和今日内容

    Django静态文件引用优化
    存在两种引用方式:
    1、方式1

    2、方式2

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            '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',
                    'django.core.context_processors.static',      #新增的内容
                ],
            },
        },
    ]
    
    STATIC_URL = '/static/'
    settings

    为什么?

    def static(request):
        """
        Adds static-related context variables to the context.
        """
        return {'STATIC_URL': settings.STATIC_URL}
    from django.core.context_processors import static

    对于views文件和templates来讲,在涉及较大量的时候,都应该进行分类处理,比如viewsaccount.py类处理登录的函数,templatesaccount下的html文件为登录相关的html文件,如下

    from django.conf.urls import url,include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^', include("app01.urls")),
    ]
    urls
    from django.conf.urls import url,include
    from django.contrib import admin
    from  app01.views import account
    
    urlpatterns = [
        url(r'^login/', account.login),
    ]
    app01/urls
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django.shortcuts import render
    def login(request):
        return render(request, "account/login.html")
    account.py
    {% load staticfiles %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>abcd</h1>
        <h1>{{ STATIC_URL }}</h1>
        <script src="/static/js/jquery-2.1.4.min.js"></script>
        <script src="{{ STATIC_URL }}js/jquery-2.1.4.min.js"></script>
        <script src="{% static "js/jquery-2.1.4.min.js"%}"></script>
    
    </body>
    </html>
    login.html

    Form基本功能应用之保存用户输入内容


    1、对于不同的函数使用的form,应该进行分类:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django import forms
    class LoginForm(forms.Form):
        username = forms.CharField()            #字符串
        password = forms.CharField(widget=forms.PasswordInput)   #没有字符串的设定格式,通过widget进行设置
    formaccount.py

    2、普通render方式如下,无法保存用户输入内容

    点击submit之后,如果用户密码或用户名输入错误,密码和用户名输入框就会都变为空;

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django.shortcuts import render
    from  app01.forms import account as AccountForm
    def login(request):
        '''
        if request.method == "POST":
            inp_obj = AccountForm.LoginForm(request.POST)       #封装了数据的对象,不仅可以做数据的验证,还可以将提交的数据再次显示到页面上去;
            return render(request, "account/login.html",{'obj':inp_obj})'''
        obj = AccountForm.LoginForm()
        return render(request, "account/login.html",{'obj':obj})       #没有封装数据的对象
    viewsaccount.py

    采用如下方式,会保存用户名:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django.shortcuts import render
    from  app01.forms import account as AccountForm    #为了区分views的account,使用as
    def login(request):
        '''1、第一次登陆为get,不会执行if部分'''
        if request.method == "POST":
            inp_obj = AccountForm.LoginForm(request.POST)       #封装了数据的对象,不仅可以做数据的验证,还可以将提交的数据再次显示到页面上去;
            return render(request, "account/login.html",{'obj':inp_obj})
        obj = AccountForm.LoginForm()
        return render(request, "account/login.html",{'obj':obj})       #没有封装数据的对象
    views/account.py

    或者:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django.shortcuts import render
    from  app01.forms import account as AccountForm    #为了区分views的account,使用as
    def login(request):
        obj = AccountForm.LoginForm(request.POST)          #获取页面输入的数据
        if request.method == "POST":
            return render(request, "account/login.html",{'obj':obj})
        return render(request, "account/login.html",{'obj':obj})
    views/account.py

     Form基本功能应用之验证以及错误信息

     下面利用form对于post提交的数据进行验证

    对于error信息,有三种输出形式:

    1、as_ul

    2、as_data:用于form,和不用as_data相同;

    3、as_json:用于Ajax;

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django.shortcuts import render,HttpResponse
    from  app01.forms import account as AccountForm    #为了区分views的account,使用as
    def login(request):
        obj = AccountForm.LoginForm(request.POST)          #获取页面输入的数据
        if request.method == "POST":
            if obj.is_valid():
                all_data = obj.clean()
            else:
                #Form表单提交
                error = obj.errors
                print type(error)
                print error['username'],type(error['username'])
                print error['username'][0],type(error['username'][0])
                print error['username'][0]
                print error['password'][0]
                '''
                1、as_ul
                2、as_data
                3、as_json
               '''
                #Ajax
                #error = obj.errors.as_json()
                #return HttpResponse(error)
                #print error,type(error)
            return render(request, "account/login.html",{'obj':obj,'error':error})
        return render(request, "account/login.html",{'obj':obj})   #form返回obj对象
        #如果是ajax的话,return HttpReponse("字符串或者字符串类型的字典,不能为obj对象")
    viewsaccount.py
    {% load staticfiles %}
    {% load xx %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/login/" method="post">
            <p>{{ obj.username }}
                <span style="color: red;">{% error_msg error.username %}</span>    #因为模板语言不支持obj.username[0]的方式取第一个错误信息,所以通过simple_tag来实现
            </p>
            <p>{{ obj.password }}</p>
            <input type="submit" value="submit" />
    
        </form>
        <h1>abcd</h1>
        <script src="/static/js/jquery-2.1.4.min.js"></script>
        <script src="{% static "js/jquery-2.1.4.min.js"%}"></script>
        <script>
    
    
        </script>
    
    </body>
    </html>
    login.html
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    from django import template
    from django.utils.safestring import mark_safe
    from django.template.base import resolve_variable, Node, TemplateSyntaxError
    
    register = template.Library()
    @register.simple_tag
    def error_msg(error_list):
        if error_list:
            return error_list[0]
        return ""
    templatetagsxx.py

    下面利用Ajax推数据进行提交:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django.shortcuts import render,HttpResponse
    from  app01.forms import account as AccountForm    #为了区分views的account,使用as
    def login(request):
        obj = AccountForm.LoginForm(request.POST)          #获取页面输入的数据
        if request.method == "POST":
            if obj.is_valid():
                all_data = obj.clean()
            else:
                #Form表单提交
                error = obj.errors
                print type(error)
                #print error['username'],type(error['username'])
                #print error['username'][0],type(error['username'][0])
                #print error['username'][0]
                #print error['password'][0]
                '''
                1、as_ul
                2、as_data
                3、as_json
               '''
                #Ajax
                error = obj.errors.as_json()
                return HttpResponse(error)
                print error,type(error)
            return render(request, "account/login.html",{'obj':obj,'error':error})
        return render(request, "account/login.html",{'obj':obj})   #form返回obj对象
        #如果是ajax的话,return HttpReponse("字符串或者字符串类型的字典,不能为obj对象")
    viewsaccount.py
    {% load staticfiles %}
    {% load xx %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/login/" method="post">
            <p>{{ obj.username }}
                <span style="color: red;">{% error_msg error.username %}</span>
            </p>
            <p>{{ obj.password }}</p>
            <input type="submit" value="submit" />
            <input type="button" onclick="SubmitAjax();" value="Ajax" />
    
        </form>
        <h1>abcd</h1>
        <script src="/static/js/jquery-2.1.4.min.js"></script>
        <script src="{% static "js/jquery-2.1.4.min.js"%}"></script>
        <script>
            function SubmitAjax(){
                $.ajax({
                    'url':'/login/',
                    type:'POST',
                    data: {'username':'','password':''},
                    success:function(arg){
                        console.log(arg);
                    }
            })
            }
    
        </script>
    
    </body>
    </html>
    login.html

     Form功能应用之自动生成select标签


    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    from django.shortcuts import render
    from app01.forms import home as HomeForm
    def index(request):
        obj = HomeForm.ImportForm()
        return render(request,'home/index.html',{'obj':obj})
    viewshome.py
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django import forms
    class ImportForm(forms.Form):
        HOST_TYPE_LIST = (
            (1,'物理机'),
            (2,'虚拟机')
        )
        host_type = forms.IntegerField(
            widget=forms.Select(choices=HOST_TYPE_LIST)
        )
        hostname = forms.CharField()
        import json
        '''
        f = open('db_admin','w')
        dic = ((1,"Charles"),(2,"wahaha"))
    
        f.write(json.dumps(dic))
        f.close()
        '''
        fr = open('db_admin')
        data = fr.read()
        print data,type(data)
        data_tuple = json.loads(data)
        fr.close()
        admin = forms.IntegerField(
            widget=forms.Select(choices=data_tuple)
        )
        '''如果没有下面的构造方法,在配置文件db_admin内容修改之后,select下面选择的内容不会改变;
        原因是根据类的定义,其静态字段在程序启动的时候会在内存中加载一次之后不会再改变,除非类重新加载(程序重启)
        因为静态字段是存在于类中的,而对于self.的方法,其存在于对象中,在对象被重新赋值的时候,值会改变,这样可以在刷新页面的
        时候,select下面的选择内容会改变'''
        def __init__(self, *args, **kwargs):
            super(ImportForm, self).__init__(*args, **kwargs)
            fr = open('db_admin')
            import json
            data = fr.read()
            print data,type(data)
            data_tuple = json.loads(data)
            fr.close()
            self.fields['admin'].widget.choices = data_tuple
    formshome.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>录入数据</h1>
        <form action="/index/">
            <p>{{ obj.host_type }}</p>
            <p>{{ obj.hostname }}</p>
            <p>{{ obj.admin }}</p>
        </form>
        <h1>数据列表</h1>
    
    </body>
    </html>
    index.html
    [[1, "Charles"], [2, "www"],[3,"ddddd"],[4,"gggggg"]]
    db_admin

    Form功能之生成动态select标签

    上述代码可以进行优化:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django import forms
    class ImportForm(forms.Form):
        HOST_TYPE_LIST = (
            (1,'物理机'),
            (2,'虚拟机')
        )
        host_type = forms.IntegerField(
            widget=forms.Select(choices=HOST_TYPE_LIST)
        )
        hostname = forms.CharField()
        admin = forms.IntegerField(
            widget=forms.Select()            #获取空值,在下面执行__init__方法的时候重新赋值
        )
        '''如果没有下面的构造方法,在配置文件db_admin内容修改之后,select下面选择的内容不会改变;
        原因是根据类的定义,其静态字段在程序启动的时候会在内存中加载一次之后不会再改变,除非类重新加载(程序重启)
        因为静态字段是存在于类中的,而对于self.的方法,其存在于对象中,在对象被重新赋值的时候,值会改变,这样可以在刷新页面的
        时候,select下面的选择内容会改变'''
        def __init__(self, *args, **kwargs):
            super(ImportForm, self).__init__(*args, **kwargs)
            fr = open('db_admin')      #在使用models的时候,可以使用数据库获取数据
            import json
            data = fr.read()
            print data,type(data)
            data_tuple = json.loads(data)
            fr.close()
            self.fields['admin'].widget.choices = data_tuple
    formshome.py

    Model创建表之基础字段:

    model中的数据库的错做为ORM;数据库通过model中的类表示,对象为其中的一行数据,对象.id ,对象.value为每行里面的数据;

    其中settings中配置数据库:

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    }

    #!/usr/bin/env python
    #coding:utf-8
    from __future__ import unicode_literals
    from django.db import models
    
    # Create your models here.
    #ORM
    #类-->数据库
    #对象-->一行数据
    #对象.id 对象.value -->每行里面的数据
    
    class UserInfo(models.Model):         #默认情况下,表会生成两列
        name = models.CharField(max_length=32)
        ctime = models.DateTimeField(auto_now=True)   #创建时间字段,数据为当前时间
        uptime = models.DateTimeField(auto_now_add=True)    #更新数据,日期自动添加
        email1 = models.EmailField(max_length=32,null=True)    #表中添加一列,数据为null
        email2 = models.EmailField(max_length=32,default='123@123.com')   #表中添加一列,数据为'123@123.com'
        def __unicode__(self):     #输出对象的时候,输出数据库中一行数据为name的一列
            return self.name
    app01model
    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    from django.shortcuts import render
    from app01.forms import home as HomeForm
    from  app01 import models
    def index(request):
        models.UserInfo.objects.all().delete()     #删除数据
        before = models.UserInfo.objects.all()        #获取所有数据
        models.UserInfo.objects.create(name = 'Charles')    #添加数据
        after = models.UserInfo.objects.all()
    
        print before
        print after
        print after[0].ctime
        obj = HomeForm.ImportForm()
        return render(request,'home/index.html',{'obj':obj})
    viewshome.py

    python manage.py syncdb命令同步数据库表,需要事先将app注册到settings中;

     

    #!/usr/bin/env python
    #coding:utf-8
    from __future__ import unicode_literals
    from django.db import models
    
    # Create your models here.
    #ORM
    #类-->数据库
    #对象-->一行数据
    #对象.id 对象.value -->每行里面的数据
    
    class UserInfo(models.Model):         #默认情况下,表会生成两列
        name = models.CharField(max_length=32)
        ctime = models.DateTimeField(auto_now=True)   #创建时间字段,数据为当前时间
        uptime = models.DateTimeField(auto_now_add=True)    #更新数据,日期自动添加
        email1 = models.EmailField(max_length=32,null=True)    #表中添加一列,数据为null
        email2 = models.EmailField(max_length=32,default='123@123.com')   #表中添加一列,数据为'123@123.com'
        ip=models.GenericIPAddressField(protocol="ipv4")
        img = models.ImageField(null=True,blank=True,upload_to="upload")    #blank=True表示在admin后台管理的时候允许为空   upload_to表示图片上传的路径,默认会自动创建
    
        def __unicode__(self):     #输出对象的时候,输出数据库中一行数据为name的一列
            return self.name
    app01model.py

    通过admin来管理数据库表:

    from django.contrib import admin
    
    # Register your models here.
    from app01 import models
    admin.site.register(models.UserInfo)
    app01admin.py

    Model创建表之字段参数:

    1、models.AutoField  自增列 = int(11)
      如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
    2、models.CharField  字符串字段
      必须 max_length 参数
    3、models.BooleanField  布尔类型=tinyint(1)
      不能为空,Blank=True
    4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
      继承CharField,所以必须 max_lenght 参数
    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正则表达式)
    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  字符串,地址正则表达式
    22、models.BinaryField  二进制
    23、models.ImageField   图片
    24、models.FilePathField 文件
    
    更多字段
    更多字段参数
    AutoField()
    BooleanField()
    CharField()
    CommaSeparatedIntegerField()
    DateField()
    DateTimeField()
    DecimalField()
    EmailField()
    FilePathField()
    FloatField()
    IntegerField()
    BinIntegerField()
    IPAddressField()
    TextField()
    TimeField()
    URLField()
    BinaryField()
    model字段

    下面介绍通过Django上传文件示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form action="/upload/" method="POST"  enctype="multipart/form-data">  //enctype="multipart/form-data"表示多个文件上传  
            <p><input type="file" name="f1"/></p>
            <p><input type="file" name="f2"/></p>
            <p><input type="text" name="hostname"/></p>
            <input type="submit" value="upload"/>
        </form>
    </body>
    </html>
    template/home/upload.html
    def upload(request):
        if request.method=='POST':
            inp_post = request.POST    #获取所有的text文本信息
            inp_files=request.FILES    #获取所有的上传的文件信息
            file_obj1 = inp_files.get('f1')
            print file_obj1.name,type(file_obj1)   #获取上传文件的文件名
            print '333333333'
            print inp_post
            f = open(file_obj1.name,'wb')
            for line in file_obj1.chunks():    #chunks表示将文件进行切片,然后写入通过内存写入文件
                f.write(line)
            f.close()
    
        return render(request,'home/upload.html')
    app01/views/home.py

     Model创建表之一对多:外键,让两张表建立关系;

    #!/usr/bin/env python
    #coding:utf-8
    from __future__ import unicode_literals
    from django.db import models
    
    # Create your models here.
    #ORM
    #类-->数据库
    #对象-->一行数据
    #对象.id 对象.value -->每行里面的数据
    
    class UserInfo(models.Model):         #默认情况下,表会生成两列
        USER_TYPE_LIST=(
            (1,'f'),
            (2,'m'),
        )
        user_type = models.IntegerField(choices=USER_TYPE_LIST,default=1)
        name = models.CharField(max_length=32,primary_key=True,verbose_name="姓名",unique=True)
        ctime = models.DateTimeField(auto_now=True,)   #创建时间字段,数据为当前时间
        uptime = models.DateTimeField(auto_now_add=True,db_column="SB")    #更新数据,日期自动添加
        email1 = models.EmailField(max_length=32,null=True)    #表中添加一列,数据为null
        email2 = models.EmailField(max_length=32,default='123@123.com')   #表中添加一列,数据为'123@123.com'
        ip=models.GenericIPAddressField(protocol="ipv4")
        img = models.ImageField(null=True,blank=True,upload_to="upload")    #blank=True表示在admin后台管理的时候允许为空
    
        def __unicode__(self):     #输出对象的时候,输出数据库中一行数据为name的一列
            return self.name
    
    
    class Color(models.Model):
        name = models.CharField(max_length=16)
    
    class Somthing(models.Model):
        c1 = models.CharField(max_length=10)
        c2 = models.CharField(max_length=10)
        c3 = models.CharField(max_length=10)
        c4 = models.CharField(max_length=10)
        color = models.ForeignKey(Color)     #将两张表通过外键进行关联
    
    class Business(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=16)
    
    class Host(models.Model):
        hostname = models.CharField(max_length=16)
        business = models.ForeignKey('Business',to_field='nid')   #指定app01business表的nid列为外键
    app01/model.py

    >python manage.py makemigrations    

    python manage.py migrate

    更新表结构;

     

    Model创建表之多对多:一个人可以属于多个组,一个组可以包含多个人;

     需要创建第三张表,关联用户ID和组ID;

    class UserGroup(models.Model):
        group_name = models.CharField(max_length=16)
    
    class User(models.Model):
        name = models.CharField(max_length=16)
        email = models.CharField(max_length=16)
        mobile = models.CharField(max_length=16)
        user_user_group= models.ManyToManyField('UserGroup')    #创建的第三张表,将UserGroup表id和User表的id进行关联
    app01/model.py

    Model创建表之一对一:实际在数据库表创建的时候不存在;同一张表的同一列不能有重复的数据,否则不能insert进去;就是在一对多的基础上加上了不能重复的要求;

        比如用户名:密码:id等不能重复;

    class User2(models.Model):
        name = models.CharField(max_length=16)
        email = models.CharField(max_length=16)
        mobile = models.CharField(max_length=16)
    
    class AAdmin(models.Model):
        username = models.CharField(max_length=16)
        password = models.CharField(max_length=16)
        user_info = models.OneToOneField('User2')   #一对一两张表关联
    app01/model.py

     Model操作表之基础操作

     增:

    model.Tb1.objects.create(c1='xx',c2='oo') 
    或者
    obj = model.Tb1(c1='xx',c2='oo')
    obj.save()
    或者
    dic = {'c1':'xx','c2':'oo'}     #可以将form提交的数据传入
    model.Tb1.objects.create(**dic)

    查:

    model.Tb1.objects.get(id=123)  #获取一行,如果不存在,抛异常
    model.Tb1.objects.all()    #获取全部
    model.Tb1.objects.filter(name='seven','gender':'0')  #获取数据,可以用**dic替代括号中的内容
    
    model.Tb1.objects.all().first()    #获取第一条数据
    View Code

    删:

    model.Tb1.objects.filter(name='seven').delete()  

    改:

    model.Tb1.objects.filter(name='seven').update(gender='0')   #括号中的内容都可以通过**dic来替代
    
    或者:
    obj=model.Tb1.objects.get(id=1)   #获取对象
    obj.c1='111'
    obj.save()

    好了,上面是关于表操作的基础部分,下面开始介绍如何在实际中操作:

    1、创建表SimpleModel

    class SimpleModel(models.Model):
        username = models.CharField(max_length=64)
        password = models.CharField(max_length=64)
    app01/model.py

    2、表数据的增加和查询:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    from django.shortcuts import render
    from app01.forms import home as HomeForm
    from  app01 import models
    def index(request):
        dic = {'username':'QQ','password':'123'}
        models.SimpleModel.objects.create(**dic)
        ret = models.SimpleModel.objects.all()
        print ret,type(ret),ret.query
        ret = models.SimpleModel.objects.all().values('username')
        print ret,type(ret)
        ret = models.SimpleModel.objects.all().values_list('username')
        print ret,type(ret)
        ret = models.SimpleModel.objects.all().values_list('id','username')
        print ret,type(ret)
        obj = HomeForm.ImportForm()
        return render(request,'home/index.html',{'obj':obj})
    app01/views/home.py

    3、替代之前将select的内容写入配置文件中的方式,采用数据库的方式:app01/forms/home.py

    from django import forms
    from app01 import models
    class ImportForm(forms.Form):
        HOST_TYPE_LIST = (
            (1,'物理机'),
            (2,'虚拟机')
        )
        host_type = forms.IntegerField(
            widget=forms.Select(choices=HOST_TYPE_LIST)
        )
        hostname = forms.CharField()
        admin = forms.IntegerField(
            widget=forms.Select()            #获取空值,在下面执行__init__方法的时候重新赋值
        )
        '''如果没有下面的构造方法,在配置文件db_admin内容修改之后,select下面选择的内容不会改变;
        原因是根据类的定义,其静态字段在程序启动的时候会在内存中加载一次之后不会再改变,除非类重新加载(程序重启)
        因为静态字段是存在于类中的,而对于self.的方法,其存在于对象中,在对象被重新赋值的时候,值会改变,这样可以在刷新页面的
        时候,select下面的选择内容会改变'''
        def __init__(self, *args, **kwargs):
            super(ImportForm, self).__init__(*args, **kwargs)
            self.fields['admin'].widget.choices = models.SimpleModel.objects.all().values_list('id','username')
            '''
            fr = open('db_admin')      #在使用models的时候,可以使用数据库获取数据
            import json
            data = fr.read()
            print data,type(data)
            data_tuple = json.loads(data)
            fr.close()
            self.fields['admin'].widget.choices = data_tuple
    View Code

    4、将该数据库可以通过admin后台进行管理:

    from django.contrib import admin
    
    # Register your models here.
    from app01 import models
    admin.site.register(models.UserInfo)
    admin.site.register(models.SimpleModel)
    app01/admin.py

    Admin定制:

    class School(models.Model):
        name = models.CharField(max_length=128,unique=True)
        city = models.CharField(max_length=64)
        addr = models.CharField(max_length=128)
    
        def __unicode__(self):
            return self.name
    
    class UserProfile(models.Model):
        user = models.OneToOneField(User) #alex
        name = models.CharField(max_length=64)
        school = models.ForeignKey('School')
    
    
    class ClassList(models.Model):
        course = models.ForeignKey(Course,verbose_name=u"课程")
        semester = models.IntegerField(verbose_name=u"学期")
        course_type = models.CharField(max_length=64,choices=course_type_choices,default='offline_weekend')
        teachers = models.ManyToManyField(UserProfile)
        start_date = models.DateField()
        graduate_date = models.DateField()
    

      

    定制代码如下:

    from django.contrib import admin
    import models
    # Register your models here.
    
    
    class UserProfileAdmin(admin.ModelAdmin):
        list_display = ('id','user','name','school')     #定义要显示的字段,不能是多对多的字段
        search_fields = ('name','school__name')      #可以被搜索的字典,如果是通过外键关联,使用__表示
        list_filter = ('name','school__name')            #定义右侧通过哪些字段过滤出来的内容
        list_editable = ('name','user','school')      #定义哪些字段可以直接被编辑的
        list_per_page = 10                   #定义每页显示几行数据
        raw_id_fields = ('user','school')          #如果是通过外键关联的字段,可能存在许多选择的内容,优化选择
    
    
    class ClassListAdmin(admin.ModelAdmin):
        list_display = ('course','semester','course_type','start_date','graduate_date')
        filter_horizontal = ('teachers',)          #多对多的字段,显示更加明显
    admin.site.register(models.UserProfile,UserProfileAdmin)
    admin.site.register(models.Customer)
    admin.site.register(models.CustomerTrackRecord)
    admin.site.register(models.ClassList,ClassListAdmin)
    admin.site.register(models.Course)
    admin.site.register(models.CourseRecord)
    admin.site.register(models.StudyRecord)
    admin.site.register(models.School)
    

     还有xadmin可以定制化漂亮的admin展示,有兴趣可以自己查!!

     

    自定义Admin action

    默认的admin action只要批量选择删除的功能,action只有在批量的时候才会有用;

    def changeschool(modelAdmin,request,queryset):
        print '--->',request,queryset
        queryset.update(school=2)
        changeschool.short_description=u'set 2'
    
    
    def changeschool1(modelAdmin,request,queryset):
        print '--->',request,queryset
        queryset.update(school=1)
        changeschool1.short_description=u'set 1'
    
    
    class UserProfileAdmin(admin.ModelAdmin):
        list_display = ('id','user','name','school')
        search_fields = ('name','school__name')
        list_filter = ('name','school__name')
        list_editable = ('name','user','school')
        list_per_page = 10
        raw_id_fields = ('user','school')
        actions = [changeschool,changeschool1,]
    

      

    Admin定制之加颜色

    首先在model中定义方法:

    class Customer(models.Model):
        qq = models.CharField(max_length=64,unique=True)
        name = models.CharField(verbose_name=u"姓名",max_length=32,blank=True,null=True)
        phone = models.BigIntegerField(blank=True,null=True)
        course = models.ForeignKey('Course')
    
        course_type = models.CharField(max_length=64,choices=course_type_choices,default='offline_weekend')
        consult_memo = models.TextField()
        source_type_choices = (('qq',u"qq群"),
                       ('referral',u"内部转介绍"),
                       ('51cto',u"51cto"),
                       ('agent',u"招生代理"),
                       ('others',u"其它"),
                       )
    
        source_type = models.CharField(max_length=64,choices=source_type_choices)
    
        def choice_source(self):
            if self.source_type == 'qq':
                format_td = format_html('<span style="padding:2px;background-color:pink;color:white"> %s</span>' %self.source_type)
            elif self.source_type == 'referral':
                format_td = format_html('<span style="padding:2px;background-color:pink;color:white"> %s</span>'%self.source_type)
            else:
    
                format_td = format_html('<span style="padding:2px;background-color:pink;color:blank"> %s</span>' %self.source_type)
            return format_td
    
        choice_source.short_description='source_type'     #修改admin显示的字段
    

      将定义的函数注册到Admin中:

    class CustomerAdmin(admin.ModelAdmin):
        list_display = ('source_type','choice_source')
    

    效果如下:

     Model操作表之进阶操作:

    获取个数:
    models.Tb1.objects.filter(name='seven').count()
    
    大于,小于
    models.Tb1.objects.filter(id__gt=1)
    models.Tb1.objects.filter(id__lt=1)
    models.Tb1.objects.filter(id__lt=10,id_gt=1)
    
    in
    models.Tb1.objects.flter(id__in=[11,22,33])
    models.Tb1.objects.exclude(id__in=[11,22,33])
    
    contains   类似于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])    #between  and
    
    
    其他类似:
    startwith,istartwith,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'))
    models.Tb1.objects.all().values(id).annotate(c=Count('num'))    #以id进行分组,并计算相同组的num的最大值、最小值、和、个数等;
    View Code

     连表操作(数据库数据插入和数据查询展示),一对多操作

    1、创建用户组表和用户组表,并通过外键进行关联

    class UserGroup_NEW(models.Model):
        caption = models.CharField(max_length=64)
        def __unicode__(self):
            return self.caption
    
    
    class User_NEW(models.Model):
        username = models.CharField(max_length=64)
        user_group = models.ForeignKey('UserGroup_NEW')   #默认创建的外键会加上_id,可以使用db_clomn来修改为自定义的列名
        def __unicode__(self):
            return self.username
    app01/models.py

    2、form

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    
    from django import forms
    from app01 import models
    class UserForm(forms.Form):
        username = forms.CharField()
        user_group_id = forms.IntegerField(       #采用方式2直接插入数据的话,需要加_id
            widget=forms.Select()            #获取空值,在下面执行__init__方法的时候重新赋值
        )
        def __init__(self, *args, **kwargs):
            super(UserForm, self).__init__(*args, **kwargs)
            self.fields['user_group_id'].widget.choices = models.UserGroup_NEW.objects.all().values_list('id','caption')
    app01/forms/foreign.py

    3、数据插入方式有两种:a、通过对象插入;b、直接插入;

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    from django.shortcuts import HttpResponse,render
    from app01 import models
    from app01.forms import foreign as ForgienForm
    def create_user_group(request):
        # models.UserGroup_NEW.objects.create(caption='CEO')    #向用户组中添加数据
        # models.UserGroup_NEW.objects.create(caption='CTO')
        # models.UserGroup_NEW.objects.create(caption='COO')
        return HttpResponse('ok')
    
    def create_user(request):
        obj = ForgienForm.UserForm(request.POST)
        if request.method =="POST":
            print "数据提交"
            #print request.POST
            if obj.is_valid():
                all_data = obj.clean()
                print all_data
                #获取对象
                # group_obj = models.UserGroup_NEW.objects.get(all_data['use_group'])      方式1  通过对象级别插入数据,group_obj代表对象,是一列数据
                # models.User_NEW.objects.create(hostname=all_data['username'],
                #                                user_group=group_obj)
                # models.User_NEW.objects.create(hostname=all_data['username'],
                #                                user_group_id=all_data['user_group'])   #方式2:可以通过两种方式插入数据,默认在Django中插入外键会加_id,
                                                                                         #此种方法可以直接插入数据
                models.User_NEW.objects.create(**all_data)     #将方式2直接修改为此种方式创建数据
                print models.User_NEW.objects.all().count()
            else:
                pass
        user_list = models.User_NEW.objects.all()    #数据查询
        print user_list
        return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
    app01/views/foreign.py

    4、html模板文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/create_user/" method="post">
        <p>{{ obj.username }}</p>
        <p>{{ obj.user_group_id }}</p>
        <input type="submit" value="submit"/>
    </form>
        <table>
            {% for item in user_list %}
            <tr>
                <td>{{ item.username }}</td>
               <td>{{ item.user_group.caption }}</td>      {# 因为在model中的外键等一对多的操作,表示对象(就是一行数据),然后取一行数据的单独一列#}
            </tr>
            {% endfor %}
        </table>
    </body>
    </html>
    create_user.html
    [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>]
    [26/Jun/2016 17:40:50] "GET /create_user/ HTTP/1.1" 200 894
    数据提交
    {'username': u'wahaha', 'user_group_id': 1}
    5
    [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>]
    [26/Jun/2016 17:41:03] "POST /create_user/ HTTP/1.1" 200 1023
    [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>]
    [26/Jun/2016 17:46:27] "GET /create_user/ HTTP/1.1" 200 1013
    数据提交
    {'username': u'aaa', 'user_group_id': 1}
    6
    [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>, <User_NEW: aaa>]
    [26/Jun/2016 17:46:34] "POST /create_user/ HTTP/1.1" 200 1141
    结果

    通过get的方式获取想要查询的数据:

    1、直接get获取数据库中的数据

    def create_user(request):
        obj = ForgienForm.UserForm(request.POST)
        if request.method =="POST":
            print "数据提交"
            #print request.POST
            if obj.is_valid():
                all_data = obj.clean()
                print all_data
                #获取对象
                # group_obj = models.UserGroup_NEW.objects.get(all_data['use_group'])      方式1  通过对象级别插入数据,group_obj代表对象,是一列数据
                # models.User_NEW.objects.create(hostname=all_data['username'],
                #                                user_group=group_obj)
                # models.User_NEW.objects.create(hostname=all_data['username'],
                #                                user_group_id=all_data['user_group'])   #方式2:可以通过两种方式插入数据,默认在Django中插入外键会加_id,
                                                                                         #此种方法可以直接插入数据
                models.User_NEW.objects.create(**all_data)     #将方式2直接修改为此种方式创建数据
                print models.User_NEW.objects.all().count()
            else:
                pass
        val = request.GET.get('username')    #通过get的方式获取数据
        user_list = models.User_NEW.objects.filter(username=val)    #数据查询
        # user_list = models.User_NEW.objects.all()    #数据查询
        print user_list
        return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
    app01/views/foreign.py

    2、get通过对象获取数据

    ####通过双下划线实现
    def create_user(request):
        obj = ForgienForm.UserForm(request.POST)
        if request.method =="POST":
            print "数据提交"
            #print request.POST
            if obj.is_valid():
                all_data = obj.clean()
                print all_data
                #获取对象
                # group_obj = models.UserGroup_NEW.objects.get(all_data['use_group'])      方式1  通过对象级别插入数据,group_obj代表对象,是一列数据
                # models.User_NEW.objects.create(hostname=all_data['username'],
                #                                user_group=group_obj)
                # models.User_NEW.objects.create(hostname=all_data['username'],
                #                                user_group_id=all_data['user_group'])   #方式2:可以通过两种方式插入数据,默认在Django中插入外键会加_id,
                                                                                         #此种方法可以直接插入数据
                models.User_NEW.objects.create(**all_data)     #将方式2直接修改为此种方式创建数据
                print models.User_NEW.objects.all().count()
            else:
                pass
        # val = request.GET.get('username')    #通过get的方式获取数据
        # user_list = models.User_NEW.objects.filter(username=val)    #数据查询
        # user_list = models.User_NEW.objects.all()    #数据查询
        val = request.GET.get('usergroup')        #get获取对象的数据,通过__实现
        user_list = models.User_NEW.objects.filter(user_group__caption=val)
        print user_list
        return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
    app01/views/foreign.py

    注意:1、在连表操作的时候,ForeignKey对应的行表示对象;2、添加数据的时候,默认需要在对应的列的名称后面加_id;3、获取数据的时候,如果是使用模板语言,可以使用item.user_group.caption来获取另外一张表的数据;如果使用filter查询指定的数据,使用双下划线__来获得另外一张表对应的数据;

    总结作业:

    1、user_group对应对象;

    2、创建数据  user_group_id;

    3、获取数据   通过模板加.

    4、查询数据    filter加__   两个下划线表示跨一张表;

    如果存在多张表通过外键进行关联:通过.filter(user_group__aa__name)进行数据查询

    class A(models.Model):
        name = models.CharField(max_length=12)
    
    class UserGroup_NEW(models.Model):
        caption = models.CharField(max_length=64)
        aa = models.ForeignKey('A')
        def __unicode__(self):
            return self.caption
    
    
    class User_NEW(models.Model):
        username = models.CharField(max_length=64)
        user_group = models.ForeignKey('UserGroup_NEW')   #默认创建的外键会加上_id,可以使用db_clomn来修改为自定义的列名
        def __unicode__(self):
            return self.username
    
        # .filter(user_group__aa__name)
    多张表通过外键关联

     后台也可以使用.连表来取数据:

    for item in user_list:

        print item.user_group.caption

    作业:

    xx管理:
    1、登录form
    2、session    结合装饰器
    3、装饰器
    4、主机、主机组进行关联;
          添加:主机,主机组;
          删除
          修改
          查
    
    
  • 相关阅读:
    我的技术十年
    django-cookie&session
    论学习方法
    操作系统知识
    一百天记录
    Microsoft COCO 数据集
    qt虚拟键盘编译时报错缺乏qpa/qplatforminputcontext.h文件
    ffmpeg拉取rtsp视频流
    顶层QWidget弹窗设置背景为透明,透明部分为黑色。
    ubuntu20.04 gnome桌面系统添加开机自启动GUI程序
  • 原文地址:https://www.cnblogs.com/cqq-20151202/p/5560112.html
Copyright © 2011-2022 走看看