day10图书编辑删除 字段参数choise(重要)多对多三种创建方式 ajax语法结构

day10图书编辑删除 字段参数choise(重要)多对多三种创建方式 ajax语法结构

昨日内容复习

  • Q查询

    # Q查询功能
    	1.可以改变查询条件的链接关系 比如 and or 
        2.可以改变查询条件左侧的条件(变量名>>>字符串) 
    
    from django.db.models import Q #先导入
    # 基本使用
    models.User.objects.filter(Q(title='三'),Q(price=11.11))    and
    models.User.objects.filter(Q(title='三')|Q(price=11.11))    or
    models.User.objects.filter(~Q(title='三'),Q(price=11.11))   not (title='三')and xxx
    # 进阶使用
    q_obj = Q() 
    q_obj.connector = 'or'  # 默认是and
    q_obj.children.append(('title','三'))
    q_obj.children.append(('price',11.11))
    models.User.objects.filter(q_obj)orm操作事务
    
  • orm操作事务

    from django.db import transaction
    # 方式1:装饰器
    @transaction.atomic
    # 方式2:with上下文
    with transaction.atomic():  #开启事务
    transaction.rollback() #回滚
    transaction.commit() #确认
    
  • orm查询优化

    only与defer
    	#only方法返回一个对象的数据集,里面默认存了括号内指定字段的数据,   对象点击only括号内填写的字段名称不会再走数据库查询,但是点击括号内不存在的字段名称则每次都会走数据库查询
        
        #defer和only相反 对象点字段名 ,对象点击only括号内填写的字段名称走数据库查询,但是点击括号内不存在的字段名称则不会走数据库查询
    select_related与prefetch_related
    	只能是一对一和一对多
    	select_related方法只能写外键 会执行连表操作,表拼接在一起,表中所有数据全部封装到数据对象中,之后对象无论查询哪个表的数据都不再走数据库查询 一条sql语句
        prefetch_related只能写外键 相当于子查询操作,先查询一张表 ,再把关联的表数据也查询出来,在封装到数据对象中 两条sql语句
    
  • orm字段类型和常用参数

    # orm除了提供大量的字段类型之外还支持自定义字段类型
    AutoField()
    CharField()
    DecimalField()
    DateField()
    DateTimeField()
    IntergerField()
    BigIntergerField()
    BooleanField()
    TextField()
    FileField()
    EmailField()
    ###############常用参数
    null
    default
    unique
    db_index
    max_length
    auto_now
    auto_now_add
    to
    to_field
    related_name
    verbose_name
    

今日内容概要

  • 图书的编辑

  • 图书的删除

  • 字段参数之choices(重要)

  • 多对多三种创建方式

  • MTV与MVC理论

  • ajax语法结构(固定的)

  • 请求参数contentType

  • ajax如何传文件及json格式数据

今日内容详细

  • 图书的编辑

    1.urls指定
        #图书编辑页面
        url(r'^book_edit/(\d+)',views.book_edit,name='be'),
    2.去创建对应的views视图
    def book_edit(request,edit_id):
        #1.获取用户想要编辑的数据对象
        edit_obj=models.Book.objects.filter(pk=edit_id).first()
        if request.method=='POST':
            title = request.POST.get('title')
            price = request.POST.get('price')
            publish_time = request.POST.get('publish_time')
            publish_pk = request.POST.get('publish_pk')
            author_pk_list = request.POST.getlist('author_pk_list')
            models.Book.objects.filter(pk=edit_id).update(title=title,price=price,publish_time=publish_time,publish_id=publish_pk)
            edit_obj.authors.set(author_pk_list)
            return redirect('bl')
        #2.返回一个页面 页面显示要编辑的数据
    
        #3.创建出版社对象 作者对象并返回
        publish_queryset=models.Publish.objects.all()
        author_queryset=models.Author.objects.all()
    
        return render(request,'book_edit.html',locals())
    3.返回的html界面
    {% extends 'home.html' %}
    
    {% block content %}
        <h2 class="text-center">图书编辑页面</h2>
        <form action="" method="post">
        <p>书名
            <input type="text" name="title" class="form-control" value="{{ edit_obj.title }}">
        </p>
        <p>价格
            <input type="text" name="price" class="form-control" value="{{ edit_obj.price }}">
        </p>
        <p>出版日期
            <input type="date" name="publish_time" class="form-control" value="{{ edit_obj.publish_time|date:'Y-m-d' }}">
        </p>
        <p>出版社
    {#    循环所有的出版社对象跟书籍对象出版社比对 如果一致 添加selected#}
            <select name="publish_pk" id="" class="form-control">
                {% for publish_obj in publish_queryset %}
                     {% if publish_obj == edit_obj.publish %}
                         <option value="{{ publish_obj.pk }} " selected>{{ publish_obj.name }}</option>
                     {% else %}
                         <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                     {% endif %}
    
                {% endfor %}
            </select>
        </p>
        <p>作者
            <select name="author_pk_list" id="" class="form-control" multiple>
                {% for author_obj in author_queryset %}
                    {% if author_obj in edit_obj.authors.all %}
                        <option value="{{ author_obj.pk }}" selected>{{ author_obj.name }}</option>
                    {% else %}
                        <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
    
                    {% endif %}
    
    
                {% endfor %}
    
            </select>
        </p>
            <input type="submit" value="编辑成功" class="btn btn-primary btn-group">
        </form>
    {% endblock %}
        
    
  • 图书的删除

    1.urls路由层
        #图书删除页面
        url(r'^book_delete/(?P\d+)/',views.book_delete,name='bd')
    2.views视图层
    def book_delete(request,delete_id):
        models.Book.objects.filter(pk=delete_id).delete()
        return redirect('bl')
    3.html界面
    	没有 这个就是做了一个简单删除动作 直接指向了展示页
    
  • 字段参数之choices(重要)

    有的时候我们发现表的字段有的是不能输入的只能选择 比如
    	性别字段   男 女...
    	学历字段   大专 本科 研究生 博士 ...
    诸如此类字段 推荐使用choices参数
    
    比如 1.先在models 创建一个表
    class User(models.Model):
        name=models.CharField(max_length=32)
        age=models.IntegerField()
        #先创建一个gender_choise 存放对应关系
        gender_choise=(
            (1,'男'),   #这里面数字 字符串都可以 但是保证一致 前面都是字符串 或都是数字 对应的后面都是字符串或数字
            (2,'女'),
            (3,'未知')
        )
        gender=models.IntegerField(choices=gender_choise) #这里需要用choise指定 刚才的对应关系
    2.执行数据库迁移,并存入数据
    #注意存数据时候 gender这个字段是整形  只能存定义时候有关系的 存4也行 但是获取时候只能是4
    3.创建user对象并调用gender
    import os
    
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
        import django
        django.setup()
    
        from app01 import models
        user_obj=models.User.objects.filter(pk=1).first()
        print(user_obj.gender)   # 1
        print(user_obj.get_gender_display()) #男
    '''如果没有对应关系则返回数据本身'''
    
  • 多对多三种创建方式

    #第一种:自动创建
    	定义外键的时候直接指定ManyToManyField(to='关联的表名') 就是自动创建
        优点:不用我们编写第三张关系表代码
        缺点:第三张关系表 字段固定,无法扩展
    #第二种:手动创建
    	class Book(models.Model):
            pass
        class Author(models.Model):
            pass
        class Book2Author(models.Model):
            book_id = models.ForeignKey(to='Book')  #相当于外键指到book表
            author_id = models.ForeignKey(to='Author') #相当于外键指到author
            bond_time = models.DateField(auto_now=True) #自己新增的字段
    	优点:第三张表可以无限制的扩展字段
        缺点:需要手动编写第三张表,用orm正反向查询时候不方便,不知道是正向还是反向,因为外键字段两张表都没有
    #第三种:半自动半手动创建   两张表都手动创建 第三张关系表也要手动创建  外键字段多对多 建在哪个表都行
    		class Book(models.Model):
            authors = models.ManyToManyField(
                to='Author', #指向author表
                through='Book2Author'  # 告诉orm第三张关系表是谁不要自动创
            	through_fields=('book_id','author_id')  # 在第三张表 通过哪两个字段实现了多对多 在book表 bookid在前
            )
         class Author(models.Model):
            # 多对多外键字段在orm中可以建在任意一张关联表中 上面是在book建 下面是在auhor建
            books = models.ManyToManyField(
                to='Book',
                through='Book2Author'  # 告诉orm第三张关系表是谁不要自动创
            	through_fields=('author_id','book_id')  # 通过哪两个字段 在author表 author_id 在前
            )
         class Book2Author(models.Model):
            book_id = models.ForeignKey(to='Book')
            author_id = models.ForeignKey(to='Author')
            bond_time = models.DateField(auto_now=True)
            
         
    
  • MTV与MVC理论

    MTV模型
    	M:models模型层
        T:template模板层
        V:views视图层
    
    MVC模型
    	M:models模型层
        V:views视图层
        C:controllar控制层(urls.py...)
    """
    django自称为MTV模型  其实本质也还是MVC模型
    	大部分的web框架都属于MVC
    """
    
  • ajax语法结构(固定的)

    # 特征:异步提交 局部刷新
    """使用jQuery封装的ajax一定要记得先引入ajax资源"""
    异步:提交完任务之后 不愿地等待任务的结果 执行别的 ,有返回结果 自动通过一个回调机制再回来
    比如 注册界面 你输入了用户名 他会自动传给后端 告诉你用户名已存放 或者用户名可以使用 局部刷新
    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
    """
    可以发送网络请求的标签
    	a标签			GET请求
    	form表单		GET请求 POST请求
    	
    ajax技术			GET请求 POST请求
    """
    # ajax并不是一门新的技术 而是有js代码演变而来 相当于我们python基础所学的装饰器(名称空间 函数对象 闭包函数)
    # jQuery封装之后的ajax代码(格式固定 并且语法简单 好记)
    # 其他框架也可以封装ajax技术
    
    基本语法格式 
    //1.查找计算按钮标签
               $.ajax({
                   url:'' ,  //向谁发请求(from 的action一样  不写 后缀 全路径)
                   type:'post',     //请求的方式(get post)
                   data:{'username':'zhang','pwd':123}, // 请求携带的数据数据
                   success:function (args) {  //异步回调机制(后端返回数据自动触发的操作)
                       '回调执行的操作'
    
                   }
    
    #加法运算 三个输入框 一个按钮 页面不能刷新 采用ajax
    #views
    def ab_ajax(request):
        if request.method == 'POST':
            #获取i1  i2
            i1 = request.POST.get('i1')
            i2 = request.POST.get('i2')
            res = int(i1) + int(i2)
            return HttpResponse(res)
        return render(request, 'ab_ajax.html' )
    ##############################################################################               
    #ab_ajax.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
        <input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
        <button id="d1">计算</button>
        <script>
            //1.查找计算按钮标签
            let $btnEle=$('#d1');//根据id查找标签对象
            //2.给按钮标签绑定点击事件 两种方式 on
            $btnEle.on('click',function () {
                //2.1获取输入框的内容 先查找到输入框之后获取里面的value属性
                let i1val=$('#i1').val();      //val 拿value值
                let i2val=$('#i2').val();     //val 拿value值
    
                //3.发送ajax请求
                $.ajax({
                    url:'' ,  //向谁发请求(from 的action一样  不写 后缀 全路径)
                    type:'post',     //请求的方式(get post)
                    data:{'i1':i1val,'i2':i2val}, // 请求携带的数据数据 字典的形式
                    success:function (args) {  //异步回调机制(后端返回数据自动触发的操作)
                        $('#i3').val(args)  //val(里面写内容是赋值  不写内容是拿这个框内容 )
    
                    }
                })
            })
            //第二种绑定点击事件
            {#$btnEle.click(function () {#}
            {#    alert('我不好')#}
            //})
    
        </script>
    
    </body>
    </html>
    
  • 请求参数contentType

    Content-Type: application/x-www-form-urlencoded; charset=UTF-8 #说明了数据的组织格式 后端通过该参数就可以提前明确数据格式之后采取对应的处理措施操作数据  比如提前告诉你 我要给你发什么数据
    
    Content-Type 数据类型
    	ajax磨人的数据格式为 urlencoded: i1=12&i2=2
        针对该类型的数据:django会自动处理到request.POST中  后端用request.POST接受
       
    #form表单只能发送 urlencoded 和 formdata格式数据
    form表单默认的数据格式也是urlencoded
    	该格式数据:i1=123213&i2=12313
         针对该类型的数据:django会自动处理到request.POST中 后端用request.POST接受
    form表单还可以发送数据格式为formdata
    	该格式数据无法查看到 封装成二进制发送给后端
        针对该类型的数据:普通的数据还是解析到request.POST中 文件类型的数据解析到request.FILES中
    
  • ajax如何传文件及json格式数据

"""
python中序列化反序列化
	import json
	json.dumps()
	json.loads()
Js中序列化反序列化
	JSON.stringify()
	JSON.parse()
"""
django针对json格式数据没有指定任何东西去处理 ,放在了request.body里面

#html
<body>
<button id="b1">发送json格式数据</button>
<script>
    //1.查找按钮
    let $btn=$('#b1')
    //2.给按钮绑定单击事件
    $btn.on('click',function () {
        //3.发送ajax请求
        $.ajax({
            url:'' ,//向谁发请求空为当前页面
            type:'post', //请求方式
            data:JSON.stringify({'name':'aaa','pwd':123}), //发送的数据  json数据需要序列化一下
            contentType:'application/json',   //类似于报头 指定传给你json数据
            success:function (args) {//异步回调机制(后端返回数据自动触发的操作)
                alert(args)

            }
        })
    })

</script>
</body>

#views
def ac_ajax(request):
    if request.method == 'POST':
        print(request.POST)#获取不到json格式数据 
        print(request.GET) #获取不到json格式数据 
        print(request.FILES)#获取不到json格式数据
        print(request.body)#能获取到 但是是二进制  b'{"name":"aaa","pwd":123}'
        #json.loads 可以自动解码并序列化 不需要decode了
        import json
        json_dict=json.loads(request.body)
        print(json_dict,type(json_dict))  #{'name': 'aaa', 'pwd': 123} 
        return HttpResponse('123')

    return render(request,'ac_ajax.html')

你可能感兴趣的:(django,mysql,数据库,database)