zoukankan      html  css  js  c++  java
  • Django框架基础(二)

    MODELS

     1    对数据库起效的字段设置:
     2         数据类型:CharField
     3                   IntegerField
     4                   FloatField
     5                   DecimalField(max_digits=30,decimal_places=10)
     6                   DateTimeField
     7 
     8 
     9         字段参数:null=True  default=''   unique=True   db_index=True  premary_key
    10         class Meta:
    11         unique_together=(
    12             ('email','ctime')
    13         )
    14         index_together=(
    15             ('email','ctime')
    16         )
    17 
    18    对admin起效的字段设置:
    19          数据类型:
    20                字符串:
    21             EmailField(CharField):
    22             IPAddressField(Field)
    23             URLField(CharField)
    24                     SlugField(CharField)
    25             UUIDField(Field)
    26             FilePathField(Field)
    27             FileField(Field)
    28             ImageField(FileField)
    29             CommaSeparatedIntegerField(CharField)
    30 
    31                 枚举:
    32                      color_list = (
    33                     (1,'黑色'),
    34                     (2,'白色'),
    35                     (3,'蓝色')
    36                         )
    37              color = models.IntegerField(choices=color_list)
    38                      应用场景:选项固定
    39                                 
    40              PS: FK选项动态
    41          字段参数:
    42                  verbose_name        Admin中显示的字段名称
    43                  blank               Admin中是否允许用户输入为空
    44                  editable            Admin中是否可以编辑
    45                  help_text           Admin中该字段的提示信息
    46                  choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    47                  test=models.CharField(
    48                      max_length=32,
    49                      error_messages={
    50                         'c1':'优先错误信息'
    51                            },
    52                      validators=[RegexValidator(regex='root_d+',message='error',code='c1')],
    53                      null=True
    54     )
    字段
     1 class Userinfo(models.Model):
     2     username=models.CharField(max_length=32)
     3     password=models.IntegerField(max_length=16)
     4 
     5     email=models.EmailField(null=True,default='1111',unique=True,blank=True,verbose_name='邮箱')
     6     ctime=models.DateTimeField(null=True)
     7     test=models.CharField(
     8         max_length=32,
     9         error_messages={
    10             'c1':'优先错误信息'
    11         },
    12         validators=[RegexValidator(regex='root_d+',message='error',code='c1')],
    13         null=True
    14     )
    15     color_list=(
    16         (1,'black'),
    17         (2,'white'),
    18         (3,'blue'),
    19     )
    20     color=models.IntegerField(choices=color_list)
    21 
    22     class Meta:
    23         unique_together=(
    24             ('email','ctime')
    25         )
    26         index_together=(
    27             ('email','ctime')
    28         )
    View Code

     详细见下方补充信息

    ORM数据表多对多操作:

    1 自定义第三张表:

     1     class Gril(models.Model):
     2     nick=models.CharField(max_length=64)
     3 
     4 
     5     class Boy(models.Model):
     6     name=models.CharField(max_length=64)
     7 
     8     class Love(models.Model):
     9     b=models.ForeignKey('Boy')
    10     g=models.ForeignKey('Gril')
    11     class Meta:    #设置联合唯一索引
    12         unique_together=[
    13             ('b','g'),
    14         ]
    15 
    16  查询和Alex1 有关系的姑娘
    17         obj=models.Boy.objects.filter(name='alex1').first()
    18         love_list=obj.love_set.all()
    19         for row in love_list:
    20             print(row.g.nick)
    21 
    22         love_list=models.Love.objects.filter(b__name='alex1')
    23         for row in love_list:
    24             print(row.g.nick)
    25 
    26         love_list=models.Love.objects.filter(b__name='alex1').values('g__nick')
    27         for item in love_list:
    28             print(item['g__nick'])
    29 
    30         love_list=models.Love.objects.filter(b__name='alex1').select_related('g')
    31         for obj in love_list:
    32             print(obj.g.nick)
    View Code

    2 Django自动生成关系表:

     1 class Gril(models.Model):
     2     nick=models.CharField(max_length=64)
     3     m=models.ManyToManyField('Boy')               #Django内置的多对多连表设置
     4 
     5 django 内置的多对多连表操作,不能直接对连表进行操作,可以间接操作
     6         # obj=models.Gril.objects.filter(nick='egon1').first()
     7         # print(obj.nick,obj.id)
     8         # obj.m.add(2)
     9         # obj.m.add(2,4)
    10         # obj.m.add(*[1,])
    11 
    12         # obj.m.remove(1)
    13         # obj.m.remove(*[2,4])
    14         # obj.m.set([1,])
    15 
    16         # q=obj.m.all()
    17         # print(q)     #<QuerySet [<Boy: Boy object>]>
    18         #
    19         # boy_list=obj.m.filter(name='alex1').first()
    20         # print(boy_list.name)
    21 
    22         # obj=models.Gril.objects.filter(nick='egon1').first()
    23         # obj.m.clear()
    24         #反向操作
    25         # obj=models.Boy.objects.filter(name='alex1').first()
    26         # v=obj.gril_set.all()
    27         # print(v)
    View Code

    3杂交:

     1                         class Boy(models.Model):
     2                 name = models.CharField(max_length=32)
     3                 m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))
     4                 # 查询和清空
     5 
     6             class Girl(models.Model):
     7                 nick = models.CharField(max_length=32)
     8                 # m = models.ManyToManyField('Boy')
     9 
    10             class Love(models.Model):
    11                 b = models.ForeignKey('Boy')
    12                 g = models.ForeignKey('Girl')
    13 
    14                 class Meta:
    15                     unique_together = [
    16                         ('b','g'),
    17                     ]
    View Code

    4 自关联   自定义第三张表:

     1 class UserInfo(models.Model):
     2     nickname=models.CharField(max_length=64)
     3     username=models.CharField(max_length=64)
     4     password=models.CharField(max_length=64)
     5     gender_choice=(
     6         (1,''),
     7         (2,''),
     8     )
     9     gender=models.IntegerField(choices=gender_choice)
    10 
    11 class U2U(models.Model):
    12     g=models.ForeignKey(to='UserInfo',to_field='id',related_name='boys')
    13     b=models.ForeignKey(to='UserInfo',to_field='id',related_name='grils')
    View Code
    1     xz=models.UserInfo.objects.filter(id=1).first()
    2     result=xz.gril.all()
    3     for u in result:
    4         print(u.g.nickname)
    View Code

     

     5 自关联   自动生产第三张表:

     1 class UserInfo(models.Model):
     2     nickname=models.CharField(max_length=64)
     3     username=models.CharField(max_length=64)
     4     password=models.CharField(max_length=64)
     5     gender_choice=(
     6         (1,''),
     7         (2,''),
     8     )
     9     gender=models.IntegerField(choices=gender_choice)
    10     m=models.ManyToManyField('UserInfo')
    View Code
     1     # 查男生
     2     xz = models.UserInfo.objects.filter(id=1).first()
     3     u = xz.m.all()
     4     for row in u:
     5         print(row.nickname)
     6     # 查女神
     7     xz = models.UserInfo.objects.filter(id=4).first()
     8     v = xz.userinfo_set.all()
     9     for row in v:
    10         print(row.nickname)
    11     return HttpResponse('...')
    View Code

     

    6 FK 自关联

     1 class Comment(models.Model):
     2     """
     3     评论表
     4     """
     5     news_id = models.IntegerField()            # 新闻ID
     6     content = models.CharField(max_length=32)  # 评论内容
     7     user = models.CharField(max_length=32)     # 评论者
     8     reply = models.ForeignKey('Comment',null=True,blank=True,related_name='xxxx')
     9 """
    10    新闻ID                         reply_id
    11 1   1        别比比    root         null
    12 2   1        就比比    root         null
    13 3   1        瞎比比    shaowei      null
    14 4   2        写的正好  root         null
    15 5   1        拉倒吧    由清滨         2
    16 6   1        拉倒吧1    xxxxx         2
    17 7   1        拉倒吧2    xxxxx         5
    18 """
    19 """
    20 新闻1
    21     别比比
    22     就比比
    23         - 拉倒吧
    24             - 拉倒吧2
    25         - 拉倒吧1
    26     瞎比比
    27 新闻2:
    28     写的正好
    29 """
    View Code

     

     admin

    django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin 则需要以下步骤:

    • 创建后台管理员
    • 配置url
    • 注册和配置django admin后台管理页面

    1、创建后台管理员

    1
    python manage.py createsuperuser

    2、配置后台管理url

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

    3、注册和配置django admin 后台管理页面

     a、在admin中执行如下配置

    1 from django.contrib import admin
    2   
    3 from app01 import  models
    4   
    5 admin.site.register(models.UserType)
    6 admin.site.register(models.UserInfo)
    7 admin.site.register(models.UserGroup)
    8 admin.site.register(models.Asset)
    View Code

     b、设置数据表名称

    1 class UserType(models.Model):
    2     name = models.CharField(max_length=50)
    3   
    4     class Meta:
    5         verbose_name = '用户类型'
    6         verbose_name_plural = '用户类型'
    View Code

     c、打开表之后,设定默认显示,需要在model中作如下配置

     1 from django.contrib import admin
     2   
     3 from app01 import  models
     4   
     5 class UserInfoAdmin(admin.ModelAdmin):
     6     list_display = ('username', 'password', 'email')
     7   
     8   
     9 admin.site.register(models.UserType)
    10 admin.site.register(models.UserInfo,UserInfoAdmin)
    11 admin.site.register(models.UserGroup)
    12 admin.site.register(models.Asset)
    View Code

     d、为数据表添加搜索功能

     1 from django.contrib import admin
     2   
     3 from app01 import  models
     4   
     5 class UserInfoAdmin(admin.ModelAdmin):
     6     list_display = ('username', 'password', 'email')
     7     search_fields = ('username', 'email')
     8   
     9 admin.site.register(models.UserType)
    10 admin.site.register(models.UserInfo,UserInfoAdmin)
    11 admin.site.register(models.UserGroup)
    12 admin.site.register(models.Asset)
    View Code

     e、添加快速过滤

     1 from django.contrib import admin
     2   
     3 from app01 import  models
     4   
     5 class UserInfoAdmin(admin.ModelAdmin):
     6     list_display = ('username', 'password', 'email')
     7     search_fields = ('username', 'email')
     8     list_filter = ('username', 'email')
     9       
    10   
    11   
    12 admin.site.register(models.UserType)
    13 admin.site.register(models.UserInfo,UserInfoAdmin)
    14 admin.site.register(models.UserGroup)
    15 admin.site.register(models.Asset)
    View Code

    ajax请求

    新url的方式:
    点击---href跳转页面---对应函数(GET请求)---返回另一个html文件
    ---增加或编辑---form表单提交数据--函数中数据库更新(POST请求)---重定向

    当客户端的添加或编辑按钮不经常使用时,没必要在页面开始加载时就将内容写入模态对话框,只需要在点击时触发一个ajax请求就可以获取数据
    服务端接收ajax请求一般要进行try,except捕捉异常

    为了防止读取数据库时间过长,用户体验不好,加上‘正在加载’的图片


    模态对话框的方式:
    点击---触发js事件---显示对话框(对话框中标签的内容可以是刚开始加载时就写好的,也可以是点击之后通过ajax请求得到的)
    ---增加或编辑---发送ajax请求---对应函数,更新数据库(POST请求)---返回字典---重新加载或报错

     

    ajax请求:利用模态对话框处理浏览器请求时,为了防止form表单提交数据时自动刷新页面,采用ajax向后端发送数据
    前端不会发生任何变化,数据处理结束后,后端给ajax返回一个字典,ajax根据字典来进行重新加载或报错

     1 $.ajax({
     2         url:'', #数据提交的地址
     3         type: 'get/post',
     4         data: {'key1':value,'key2':[],'k3': JSON.stringify({k1:v1,...}}, #要发送的数据,可以是字符串或列表
     5    dataType: 'JSON', #相当于json.parse(data) 将json字符串反序列化为jquery对象
     6    traditional:true, #如果ajax提交的数据有列表,则要加上traditional:true,
     7    success:function(data){
     8           if(data.status){
     9      location.reload('') #重新加载某页面
    10 
    11                location.href('/index.html?page=')+data.id   #利用ajax进行重定向
    12       }else{
    13       alert(data.message)} 
    14       })
    View Code

     中间件

    django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

    在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。

    与mange.py在同一目录下的文件夹 wupeiqi/middleware下的auth.py文件中的Authentication类

    中间件中可以定义四个方法,分别是:

    • process_request(self,request)
    • process_view(self, request, callback, callback_args, callback_kwargs)
    • process_template_response(self,request,response)
    • process_exception(self, request, exception)
    • process_response(self, request, response)

    以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

    自定义中间件

    1、创建中间件类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class RequestExeute(object):
          
        def process_request(self,request):
            pass
        def process_view(self, request, callback, callback_args, callback_kwargs):
            =1
            pass
        def process_exception(self, request, exception):
            pass
          
        def process_response(self, request, response):
            return response

    2、注册中间件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'wupeiqi.middleware.auth.RequestExeute',

     补充信息:

        AutoField(Field)
            - int自增列,必须填入参数 primary_key=True
    
        BigAutoField(AutoField)
            - bigint自增列,必须填入参数 primary_key=True
    
            注:当model中如果没有自增列,则自动会创建一个列名为id的列
            from django.db import models
    
            class UserInfo(models.Model):
                # 自动创建一个列名为id的且为自增的整数列
                username = models.CharField(max_length=32)
    
            class Group(models.Model):
                # 自定义自增列
                nid = models.AutoField(primary_key=True)
                name = models.CharField(max_length=32)
    
        SmallIntegerField(IntegerField):
            - 小整数 -32768 ~ 32767
    
        PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正小整数 0 ~ 32767
        IntegerField(Field)
            - 整数列(有符号的) -2147483648 ~ 2147483647
    
        PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正整数 0 ~ 2147483647
    
        BigIntegerField(IntegerField):
            - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
    
        自定义无符号整数字段
    
            class UnsignedIntegerField(models.IntegerField):
                def db_type(self, connection):
                    return 'integer UNSIGNED'
    
            PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
                'AutoField': 'integer AUTO_INCREMENT',
                'BigAutoField': 'bigint AUTO_INCREMENT',
                'BinaryField': 'longblob',
                'BooleanField': 'bool',
                'CharField': 'varchar(%(max_length)s)',
                'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
                'DateField': 'date',
                'DateTimeField': 'datetime',
                'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
                'DurationField': 'bigint',
                'FileField': 'varchar(%(max_length)s)',
                'FilePathField': 'varchar(%(max_length)s)',
                'FloatField': 'double precision',
                'IntegerField': 'integer',
                'BigIntegerField': 'bigint',
                'IPAddressField': 'char(15)',
                'GenericIPAddressField': 'char(39)',
                'NullBooleanField': 'bool',
                'OneToOneField': 'integer',
                'PositiveIntegerField': 'integer UNSIGNED',
                'PositiveSmallIntegerField': 'smallint UNSIGNED',
                'SlugField': 'varchar(%(max_length)s)',
                'SmallIntegerField': 'smallint',
                'TextField': 'longtext',
                'TimeField': 'time',
                'UUIDField': 'char(32)',
    
        BooleanField(Field)
            - 布尔值类型
    
        NullBooleanField(Field):
            - 可以为空的布尔值
    
        CharField(Field)
            - 字符类型
            - 必须提供max_length参数, max_length表示字符长度
    
        TextField(Field)
            - 文本类型
    
        EmailField(CharField):
            - 字符串类型,Django Admin以及ModelForm中提供验证机制
    
        IPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
    
        GenericIPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
            - 参数:
                protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
    
        URLField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证 URL
    
        SlugField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
    
        CommaSeparatedIntegerField(CharField)
            - 字符串类型,格式必须为逗号分割的数字
    
        UUIDField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
    
        FilePathField(Field)
            - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
            - 参数:
                    path,                      文件夹路径
                    match=None,                正则匹配
                    recursive=False,           递归下面的文件夹
                    allow_files=True,          允许文件
                    allow_folders=False,       允许文件夹
    
        FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
        ImageField(FileField)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
                width_field=None,   上传图片的高度保存的数据库字段名(字符串)
                height_field=None   上传图片的宽度保存的数据库字段名(字符串)
    
        DateTimeField(DateField)
            - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
        DateField(DateTimeCheckMixin, Field)
            - 日期格式      YYYY-MM-DD
    
        TimeField(DateTimeCheckMixin, Field)
            - 时间格式      HH:MM[:ss[.uuuuuu]]
    
        DurationField(Field)
            - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
    
        FloatField(Field)
            - 浮点型
    
        DecimalField(Field)
            - 10进制小数
            - 参数:
                max_digits,小数总长度
                decimal_places,小数位长度
    
        BinaryField(Field)
            - 二进制类型
    字段
        null                数据库中字段是否可以为空
        db_column           数据库中字段的列名
        db_tablespace
        default             数据库中字段的默认值
        primary_key         数据库中字段是否为主键
        db_index            数据库中字段是否可以建立索引
        unique              数据库中字段是否可以建立唯一索引
        unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
        unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
        unique_for_year     数据库中字段【年】部分是否可以建立唯一索引
    
        verbose_name        Admin中显示的字段名称
        blank               Admin中是否允许用户输入为空
        editable            Admin中是否可以编辑
        help_text           Admin中该字段的提示信息
        choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                            如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
    
        error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                            字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                            如:{'null': "不能为空.", 'invalid': '格式错误'}
    
        validators          自定义错误验证(列表类型),从而定制想要的验证规则
                            from django.core.validators import RegexValidator
                            from django.core.validators import EmailValidator,URLValidator,DecimalValidator,
                            MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                            如:
                                test = models.CharField(
                                    max_length=32,
                                    error_messages={
                                        'c1': '优先错信息1',
                                        'c2': '优先错信息2',
                                        'c3': '优先错信息3',
                                    },
                                    validators=[
                                        RegexValidator(regex='root_d+', message='错误了', code='c1'),
                                        RegexValidator(regex='root_112233d+', message='又错误了', code='c2'),
                                        EmailValidator(message='又错误了', code='c3'), ]
                                )
    参数
        class UserInfo(models.Model):
            nid = models.AutoField(primary_key=True)
            username = models.CharField(max_length=32)
            class Meta:
                # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
                db_table = "table_name"
    
                # 联合索引
                index_together = [
                    ("pub_date", "deadline"),
                ]
    
                # 联合唯一索引
                unique_together = (("driver", "restaurant"),)
    
                # admin中显示的表名称
                verbose_name
    
                # verbose_name加s
                verbose_name_plural
            
        更多:https://docs.djangoproject.com/en/1.10/ref/models/options/
    元信息
        1.触发Model中的验证和错误提示有两种方式:
            a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,如果都成功,才来检查Model的字段并显示指定错误信息
            b. 调用Model对象的 clean_fields 方法,如:
                # models.py
                class UserInfo(models.Model):
                    nid = models.AutoField(primary_key=True)
                    username = models.CharField(max_length=32)
    
                    email = models.EmailField(error_messages={'invalid': '格式错了.'})
    
                # views.py
                def index(request):
                    obj = models.UserInfo(username='11234', email='uu')
                    try:
                        print(obj.clean_fields())
                    except Exception as e:
                        print(e)
                    return HttpResponse('ok')
    
               # Model的clean方法是一个钩子,可用于定制操作,如:上述的异常处理。
    
        2.Admin中修改错误提示
            # admin.py
            from django.contrib import admin
            from model_club import models
            from django import forms
    
    
            class UserInfoForm(forms.ModelForm):
                username = forms.CharField(error_messages={'required': '用户名不能为空.'})
                email = forms.EmailField(error_messages={'invalid': '邮箱格式错误.'})
                age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'})
    
                class Meta:
                    model = models.UserInfo
                    # fields = ('username',)
                    fields = "__all__"
    
    
            class UserInfoAdmin(admin.ModelAdmin):
                form = UserInfoForm
    
    
            admin.site.register(models.UserInfo, UserInfoAdmin)
    拓展知识
  • 相关阅读:
    消息中间件
    docker 安装elasticSearch6.7.1
    Curl实现ElasticSearch的增删改查
    docker 容器的mysql主从复制
    linux上docker安装centos7.2
    linux安装docker
    调用 CURL 使用正则抓取信息
    linux 一键安装lnmp环境
    laravel框架实现数据的删除和修改
    laravel 实现增 与查
  • 原文地址:https://www.cnblogs.com/liuguniang/p/7105911.html
Copyright © 2011-2022 走看看