WEEK19:django 博客开发2

  • 路由系统 URL
    a标签中的的链接在新标签页面打开则需要添加“target=_blank”
    • 一个url对应一个网页(静态)
      函数:url(r"index/",views.index)
      类:url(r"home/",views.Home.as_view())
    • 一个url对应一类网页(动态)
      • 严格按照形式参数顺序
        url(r"detail-(\d+).html",views.detail)
        url(r'^detail-(\d+)-(\d+).html', views.detail),
        def func(request, nid, uid): #nid和pid的顺序必须先nid=2再pid=9
            pass
                    
        def func(request, *args):
            args = (2,9)
        
        def func(request, *args, **kwargs): #**kwargs为空
            args = (2,9)
      • 在正则表达式中指定形式参数
        url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) #正则表达式的分组,第一个值为nid,第二个值为uid
        url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)
        
        def func(request, nid, uid):  #nid和uid的顺序随意
            pass
            
        def funct(request, **kwargs):
            kwargs = {'nid': 1, 'uid': 3}
            
        def func(request, *args, **kwargs): #**kwargs为空
            args = (2,9)
    • name参数(urls.py)
      对URL路由关系进行命名, 以后可以根据此名称生成自己想要的URL
      #urls.py
      url(r'^asdfasdfasdf/', views.index, name='i1'),
      url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
      url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),
      
      #view.py
      def func(request, *args, **kwargs):
          from django.urls import reverse
          
          url1 = reverse('i1')                              # asdfasdfasdf/
          url2 = reverse('i2', args=(1,2,))                 # yug/1/2/
          url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/
      
      #xxx.html中的form标签中的action值为
          {% url "i1" %}               # asdfasdfasdf/
          {% url "i2" 1 2 %}           # yug/1/2/
          {% url "i3" pid=1 nid=9 %}   # buy/1/9/
      
      注:
          # 当前的URL
          request.path_info 
          当前页提交数据 action="{{ request.path_info }}"
    • 多级路由
      通过include进行路由分发
      project/urls.py
          from django.conf.urls import url,include
          from django.contrib import admin
      
          urlpatterns = [
              url(r'^cmdb/', include("app01.urls")),
              url(r'^monitor/', include("app02.urls")),
          ]
          
      app01/urls.py
          from django.conf.urls import url,include
          from app01 import views
      
          urlpatterns = [
              url(r'^login/', views.login),
          ]
          
      app02/urls.py
          from django.conf.urls import url,include
          from app02 import views
      
          urlpatterns = [
              url(r'^login/', views.login),
          ]

       



  • 视图
    • GET方法一般用来获取数据,POST方法一般用来提交数据
    • html中的input标签中的radio\checkbox\select需要一次性提交多个值的时候,在views.py中使用request.POST.getlist('xxx')获取
    • 上传文件需要在form标签中添加“ enctype="multipart/form-data" ”
      上传的文件在views.py中使用obj=request.FILES.get('xxx')获取
      获取文件名称使用obj.name
      写文件到服务端使用
      file_path=os.path.join(upload,obj.name)
      f=open(file_path,mode="wb") for i in obj.chunks(): f.write(i) f.close()
    • FBV & CBV
      • FBV
        url.py
            'home/' views.home
        views.py
            def home(request):
                 ......
      • CBV
        url.py
            'index/' views.Home.as_vies()
        views.py
            import django.views import View #继承类
            class Home(View):
                #可定义的方法:get,post,put,patch,delete,head,options,trace(点击View,跳转到base.py,查看详细的方法介绍)
                def get(self,request):  #处理get请求,函数的写法和FBV一样
                    ......
                def post(self,request):  #处理post请求
                    ......
  • 模板
  • ORM操作
    select * from tb where id > 1
    # 对应关系
    models.tb.objects.filter(id__gt=1)
    models.tb.objects.filter(id=1)
    models.tb.objects.filter(id__lt=1)
    • 创建类
      • 先写类
        from django.db import models
        
        # app01_userinfo
        class UserInfo(models.Model):
            # id列,自增,主键
            # 用户名列,字符串类型,指定长度
            username = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
        
            
      • 注册APP
        project/settings.py
        INSTALLED_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'app01',  #添加APP
        ]
      • 执行命令
        python manage.py  makemigrations #生成数据库临时文件APP/migrations/xxxx_initial.py
        python manage.py  migrate  #根据临时文件生成数据库
      • ********** 使用mysql注意 ***********
        Django默认使用MySQLdb模块链接MySQL
        主动修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码即可:
            import pymysql
            pymysql.install_as_MySQLdb()
    • 数据库
      • 字段类型
        • 基本结构
          from django.db import models
          class userinfo(models.Model):
              name = models.CharField(max_length=30)
              email = models.EmailField()
              memo = models.TextField()
        • 字段
          • 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中提供验证机制
          • 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
            数据库中字段是否可以为空
          • default 
            数据库中字段的默认值
          • primary_key
            数据库中字段是否为主键
          • db_index
            数据库中字段是否可以建立索引
          • unique
            数据库中字段是否可以建立唯一索引
          • unique_for_date
            数据库中字段【日期】部分是否可以建立唯一索引
          • unique_for_month
            数据库中字段【月】部分是否可以建立唯一索引
          • unique_for_year
            数据库中字段【年】部分是否可以建立唯一索引
          • auto_now
            创建时,自动生成时间
          • auto_now_add
            更新时,自动更新为当前时间
            #下面情况不更新时间 
            # obj = UserGroup.objects.filter(id=1).update(caption='CEO')
            #下面情况更新时间
            # obj = UserGroup.objects.filter(id=1).first()
            # obj.caption = "CEO"
            # obj.save()
          • db_column
            数据库中字段的列名
          • db_tablespace
            索引名
          • choices
            Django admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
            如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
          • blank
            Django admin中是否允许用户输入为空
          • verbose_name
            Django admin中显示的字段名称中文
          • editable
            Django admin中是否可以编辑
          • help_text
            Django admin中该字段的提示信息
          • error_messages
            Django admin自定义错误信息(字典类型),从而定制想要显示的错误信息;
            字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
            如:{'null': "不能为空.", 'invalid': '格式错误'}
          • validators
            Django form 自定义错误验证(列表类型),从而定制想要的验证规则
            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_112233\d+', 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
        • 连表结构
          • 一对多:models.ForeignKey(其他表)
            当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
            例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
          • 多对多:models.ManyToManyField(其他表)
            在某表中创建一行数据时,有一个可以多选的下拉框
            例如:创建用户信息,需要为用户指定多个爱好
          • 一对一:models.OneToOneField(其他表)
            在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了)
            例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据
          • 字段以及参数
            • ForeignKey(ForeignObject) # ForeignObject(RelatedField)
              • to  # 要进行关联的表名
              • to_field=None  # 要关联的表中的字段名称
              • on_delete=None # 当删除关联表中的数据时,当前表与其关联的行的行为
                • models.CASCADE,删除关联数据,与之关联也删除
                • models.DO_NOTHING,删除关联数据,引发错误IntegrityError
                • models.PROTECT,删除关联数据,引发错误ProtectedError
                • models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
                • models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
                • models.SET,删除关联数据
                  • 与之关联的值设置为指定值,设置:models.SET(值)
                  • 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
                    def func():
                        return 10
                    
                    class MyModel(models.Model):
                        user = models.ForeignKey(
                            to="User",
                            to_field="id"
                            on_delete=models.SET(func),)
              • related_name=None # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
              • related_query_name=None # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
              • limit_choices_to=None # 在Admin或ModelForm中显示关联数据时,提供的条件:
                • limit_choices_to={'nid__gt': 5}
                • limit_choices_to=lambda : {'nid__gt': 5}
                  from django.db.models import Q
                • limit_choices_to=Q(nid__gt=10)
                • limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                • limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
              • db_constraint=True # 是否在数据库中创建外键约束
              • parent_link=False # 在Admin中是否显示关联数据
            • OneToOneField(ForeignKey)
              • to  # 要进行关联的表名
              • to_field=None # 要关联的表中的字段名称
              • on_delete=None  # 当删除关联表中的数据时,当前表与其关联的行的行为
                # 对于一对一 
                # 1. 一对一其实就是 一对多 + 唯一索引
                # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
                # 如下会在A表中额外增加一个c_ptr_id列且唯一:
                    class C(models.Model):
                        nid = models.AutoField(primary_key=True)
                        part = models.CharField(max_length=12)
                
                    class A(C):
                        id = models.AutoField(primary_key=True)
                        code = models.CharField(max_length=1)
            • ManyToManyField(RelatedField)  
              • to # 要进行关联的表名
              • related_name=None # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
              • related_query_name=None # 反向操作时,使用的连接前缀,用于替换【表名】 , 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
              • limit_choices_to=None  # 在Admin或ModelForm中显示关联数据时,提供的条件:
                • limit_choices_to={'nid__gt': 5}
                • limit_choices_to=lambda : {'nid__gt': 5}
                  from django.db.models import Q
                • limit_choices_to=Q(nid__gt=10)
                • limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                • limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
              • symmetrical=None # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
                # 做如下操作时,不同的symmetrical会有不同的可选字段
                models.BB.objects.filter(...)
                
                # 可选字段有:code, id, m1
                    class BB(models.Model):
                
                    code = models.CharField(max_length=12)
                    m1 = models.ManyToManyField('self',symmetrical=True)
                
                # 可选字段有: bb, code, id, m1
                    class BB(models.Model):
                
                    code = models.CharField(max_length=12)
                    m1 = models.ManyToManyField('self',symmetrical=False)
              • through=None  # 自定义第三张表时,使用字段用于指定关系表
              • through_fields=None # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
                from django.db import models
                
                class Person(models.Model):
                    name = models.CharField(max_length=50)
                
                class Group(models.Model):
                    name = models.CharField(max_length=128)
                    members = models.ManyToManyField(
                        Person,
                        through='Membership',
                        through_fields=('group', 'person'),
                    )
                
                class Membership(models.Model):
                    group = models.ForeignKey(Group, on_delete=models.CASCADE)
                    person = models.ForeignKey(Person, on_delete=models.CASCADE)
                    inviter = models.ForeignKey(
                        Person,
                        on_delete=models.CASCADE,
                        related_name="membership_invites",
                    )
                    invite_reason = models.CharField(max_length=64)
              • db_constraint=True # 是否在数据库中创建外键约束
              • db_table=None  # 默认创建第三张表时,数据库中表的名称
      • 基本的增删改查
        from app01 import models  #需要引入APP的models.py,主要使用其中的函数UserInfo(定义变量类型)
        def orm(request):
            # 创建
            ###方法一:
            models.UserInfo.objects.create(username='root',password='123')
            ###方法二:
            dic = {'username': 'eric', 'password': '666'}
            models.UserInfo.objects.create(**dic)
            ###方法三:
            obj = models.UserInfo(username='alex',password='123')
            obj.save()
        
            #
            ###查找所有结果
            result = models.UserInfo.objects.all()
            #查询结果:
            # result,QuerySet => Django => []列表,userinfo的对象
            # [obj(id,username,password),obj(id,username,password), obj(id,username,password)]
            for row in result:
                print(row.id,row.username,row.password)
            print(result)
            ###查询单条记录
            result = models.UserInfo.objects.filter(username='root',password='123') #and条件
            print(result)
        #获取到的一个对象,如果不存在就报错(不建议使用,使用filter(id=1).first()
        models.UserInfo.objects.get(id=1)
        # QuerySet,返回的元素为对象
        models.UserInfo.objects.filter(id=1,name='root')
        models.UserInfo.objects.filter(id__gt=1,name='root')
        models.UserInfo.objects.filter(id__lt=1)
        models.UserInfo.objects.filter(id__gte=1)
        models.UserInfo.objects.filter(id__lte=1)
        models.UserInfo.objects.filter(id=1,name='root')
        dic = {'name': 'xx', 'age__gt': 19}
        models.UserInfo.objects.filter(**dic)
        v1 = models.Business.objects.all()
        # QuerySet,返回的元素为字典
        v2 = models.Business.objects.all().values('id','caption')
        # QuerySet,返回的元素为元组(列表)
        v3 = models.Business.objects.all().values_list('id','caption')


        # 跨表查询
        #方法一:使用.
        v = models.Host.objects.filter(nid__gt=0)
        v[0].b.caption ----> 通过符号“.”进行跨表
        #方法二:使用__
        models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','b_id','b__caption')   
        # 删除 models.UserInfo.objects.filter(username="alex").delete() # 更新 models.UserInfo.objects.filter(id=3).update(password="69")
        # dic = {'name': 'xx', 'age': 19}
        # models.UserInfo.objects.filter(id__gt=1).update(**dic)
        return HttpResponse('orm')
      • 应用:用户登录、用户信息查看、用户信息编辑等
        • app01/models.py
          from django.db import models
          # Create your models here.
          # app01_userinfo数据库表名
          class UserInfo(models.Model): #必须继承models.Model
              # id列,自增,主键
              # 用户名列,字符串类型,指定长度
              username = models.CharField(max_length=32)
              password = models.CharField(max_length=64)
        • app01/urls.py
          from app01 import views
          urlpatterns = [
              url(r'^login/', views.login),
              url(r'^index/', views.index),
              url(r'^user_info/', views.user_info),
              url(r'^userdetail-(?P<nid>\d+)/', views.user_detail),
              url(r'^userdel-(?P<nid>\d+)/', views.user_del),
              url(r'^useredit-(?P<nid>\d+)/', views.user_edit),
              url(r'^orm/', views.orm),
          ]
        • urls.py
          urlpatterns = [
              url(r'^cmdb/', include("app01.urls")),
              url(r'^monitor/', include("app02.urls")),
          ]
        • views.py
          from django.shortcuts import render,HttpResponse,redirect
          
          def login(request):
              if request.method == "GET":
                  return render(request, 'login.html')
              elif request.method == "POST":
                  # 数据库中执行 select * from user where usernam='x' and password='x'
                  u = request.POST.get('user')
                  p = request.POST.get('pwd')
                  ##判断能否登陆的方法
                  # 方法一:获取的第一个列表值是否为空(常用,能够保存查询到的信息)
                  # obj = models.UserInfo.objects.filter(username=u,password=p).first()
                  # 方法二:列表的长度是否为0
                  # count = models.UserInfo.objects.filter(username=u, password=p).count()
                  obj = models.UserInfo.objects.filter(username=u, password=p).first()
                  if obj:
                      return redirect('/cmdb/index/')
                  else:
                      return render(request, 'login.html')
              else:
                  return redirect('/index/')
          
          def index(request):
              return render(request, 'index.html')
          
          def user_info(request):
              if request.method == "GET":
                  user_list = models.UserInfo.objects.all()
                  return render(request, 'user_info.html', {'user_list': user_list})
              elif request.method == 'POST':
                  u = request.POST.get('user')
                  p = request.POST.get('pwd')
                  models.UserInfo.objects.create(username=u,password=p)
                  return redirect('/cmdb/user_info/')
          
          def user_detail(request, nid):
              obj = models.UserInfo.objects.filter(id=nid).first()
              # 取单条数据,如果不存在,直接报错
              # models.UserInfo.objects.get(id=nid)
              return render(request, 'user_detail.html', {'obj': obj})
          
          def user_del(request, nid):
              models.UserInfo.objects.filter(id=nid).delete()
              return redirect('/cmdb/user_info/')
          
          def user_edit(request, nid):
              if request.method == "GET":
                  obj = models.UserInfo.objects.filter(id=nid).first()
                  return render(request, 'user_edit.html',{'obj': obj})
              elif request.method == "POST":
                  nid = request.POST.get('id')
                  u = request.POST.get('username')
                  p = request.POST.get('password')
                  models.UserInfo.objects.filter(id=nid).update(username=u,password=p)
                  return redirect('/cmdb/user_info/')
        • index.html
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
              <style>
                  body{
                      margin: 0;
                  }
                  .menu{
                      display: block;
                      padding: 5px;
                  }
              </style>
          </head>
          <body>
              <div>
                  <div style="position: absolute;top:48px;bottom: 0;left: 0;width: 200px;background-color: brown;">
                      <a class="menu" href="/cmdb/user_info/">用户管理</a>
                      <a class="menu" href="/cmdb/user_group/">用户组管理</a>
                  </div>
              </div>
          </body>
          </html>
        • login.html
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <form action="/cmdb/login/" method="POST" enctype="multipart/form-data">
                  <p>
                      <input type="text" name="user" placeholder="用户名" />
                  </p>
                  <p>
                      <input type="password" name="pwd" placeholder="密码" />
                  </p>
                  <input type="submit" value="提交"/>
              </form>
          </body>
          </html>
        • user_info.html
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
              <style>
                  body{
                      margin: 0;
                  }
                  .menu{
                      display: block;
                      padding: 5px;
          
                  }
              </style>
          </head>
          <body>
              <div>
                  <div style="position: absolute;top:48px;bottom: 0;left: 0;width: 200px;background-color: brown;">
                      <a class="menu" href="/cmdb/user_info/">用户管理</a>
                      <a class="menu" href="/cmdb/user_group/">用户组管理</a>
                  </div>
                  <div style="position:absolute;top:48px;left: 210px;bottom: 0;right: 0;overflow: auto">
          
                      <h3>添加用户</h3>
                      <form method="POST" action="/cmdb/user_info/">
                          <input type="text" name="user" />
                          <input type="text" name="pwd" />
                          <input type="submit" value="添加"/>
                      </form>
          
                      <h3>用户列表</h3>
                      <ul>
                          {% for row in user_list %}
                              <li>
                                  <a href="/cmdb/userdetail-{{ row.id }}/">{{ row.username }}</a> |
                                  <a href="/cmdb/userdel-{{ row.id }}/">删除</a> |
                                  <a href="/cmdb/useredit-{{ row.id }}/">编辑</a>
                              </li>
                          {% endfor %}
                      </ul>
                  </div>
          
              </div>
          
          </body>
          </html>
        • user_edit.html
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
              <style>
                  body{
                      margin: 0;
                  }
                  .menu{
                      display: block;
                      padding: 5px;
          
                  }
              </style>
          </head>
          <body>
              <div>
                  <div style="position: absolute;top:48px;bottom: 0;left: 0;width: 200px;background-color: brown;">
                      <a class="menu" href="/cmdb/user_info/">用户管理</a>
                      <a class="menu" href="/cmdb/user_group/">用户组管理</a>
                  </div>
                  <div style="position:absolute;top:48px;left: 210px;bottom: 0;right: 0;overflow: auto">
                      <h1>编辑用户</h1>
                      <form method="post" action="/cmdb/useredit-{{ obj.id }}/">
                          <input style="display: none" type="text" name="id" value="{{ obj.id }}" />
                          <input type="text" name="username" value="{{ obj.username }}" />
                          <input type="text" name="password" value="{{ obj.password }}"/>
                          <input type="submit" value="提交" />
                      </form>
                  </div>
              </div>
          </body>
          </html>
        • user_detail.html
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
              <style>
                  body{
                      margin: 0;
                  }
                  .menu{
                      display: block;
                      padding: 5px;
                  }
              </style>
          </head>
          <body>
              <div>
                  <div style="position: absolute;top:48px;bottom: 0;left: 0;width: 200px;background-color: brown;">
                      <a class="menu" href="/cmdb/user_info/">用户管理</a>
                      <a class="menu" href="/cmdb/user_group/">用户组管理</a>
                  </div>
                  <div style="position:absolute;top:48px;left: 210px;bottom: 0;right: 0;overflow: auto">
                      <h1>用户详细信息</h1>
                      <h5>{{ obj.id }}</h5>
                      <h5>{{ obj.name }}</h5>
                      <h5>{{ obj.password }}</h5>
                  </div>
              </div>
          </body>
          </html>

           

posted @ 2019-11-21 22:45  飞琼君  阅读(137)  评论(0编辑  收藏  举报