django基础

django 就是一个后端的框架,每一个URL都对应一个处理函数,对应关系存储在 urls 文件中,
而处理函数放在 所建立的 APP 下的 views 文件内。
MVC框架
MVC框架的核心思想是:解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。

Web MVC各部分的功能
M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
V全拼为View,用于封装结果,生成页面展示的html内容。
C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。
创建项目的命令
django-admin startproject 项目名称
例:django-admin startproject test1
基本目录
C:.
│  manage.py
└─test1
        settings.py
        urls.py
        wsgi.py
        __init__.py

manage.py是项目管理文件,通过它管理项目。
与项目同名的目录,此处为test1。
_init_.py是一个空文件,作用是这个目录test1可以被当作包使用。
settings.py是项目的整体配置文件。
urls.py是项目的URL配置文件。
wsgi.py是项目与WSGI兼容的Web服务器入口。
创建应用
使用一个应用开发一个业务模块,此处创建应用名称为booktest,
创建应用的命令如下:python manage.py startapp booktest
运行服务器命令
python manage.py runserver ip:端口
例:python manage.py runserver
可以不写IP和端口,默认IP是127.0.0.1,默认端口为8000。
如果增加、修改、删除文件,服务器会自动重启,按ctrl+c停止服务器。

初始化设置项目中文和中国时区

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-Hans'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
需要再 next\next 下的 setting 中注释掉这句
'django.middleware.csrf.CsrfViewMiddleware'

mysite项目

建立的项目文件名称为 mysite,app 为 blog
在 mysite/blog 下建立一个static,用来存放 js,image,jquery 等静态文件,放入一个jquery
# setting 配置文件最后添加
STATIC_URL = '/static/' // 别名,指代下面的 static

STATICFILES_DIRS=(
    os.path.join(BASE_DIR, 'blog' 'static'),
)
templates 存放html文件,引入 jquery,需要在 html 中引入
{% load staticfiles %}
<script src="{% static 'jquery-3.3.1.min.js' %}"></script>

# 在浏览器端可以看到渲染之后的结果:
<script src="/static/jquery-3.3.1.min.js"></script>

# 一般引入模式
<script src="/static/jquery-3.3.1.min.js"></script>
blog 下的 urls 文件,这个文件的作用就是来存放 URL 与处理函数的关系
from django.contrib import admin
from django.urls import path
from blog import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('show_time/', views.show_time), //添加这一条
]
blog 下的 views 文件,存放处理函数
from django.shortcuts import render
import time
def show_time(request):
    # return HttpResponse("hello")
    return  render(request,"index.html",{"t":time.ctime()}) //返回一个时间
redirect 重定向,在函数的末尾返回一个重定向的网址,也就是使得django 返回执行 login URL 对应的函数
return  redirect("/login")
redirect 和 render 的区别:
用 render 代替 redirect 时,URL 不会有变化,所以刷新之后还是会跳转到原来的网址
(浏览器根本就不知道你现在的render后的网址,因为这个网页是服务器发给浏览器的,
而不是浏览器用URL去请求的)
Template 模版
组成:HTML代码+逻辑控制代码
用 context 渲染 template 模版

在模版中,如果要调用从 context 中传入的变量(变量不管是list,dict,class对象,日期,
等之类的都可以),需要用 dots  来调用值。

变量的过滤器 | (filter)

{{变量名}}
{%代码段%}

标签:{% tags %}
if,endif 结尾
    {% if a > 200 %}
        <p style="color: red;">
    {% else %}
        <p>
    {% endif %}
    libai</p>

for 在 views 定义 test = [234,'works']
    <p> test: {{ test.0 | add:10 }} </p>
    <p> test: {{ test.1 | upper }} </p>
    {% for foo in test %}
        <p>{{ forloop.counter }} : {{ foo }}</p>
    {% endfor %}
  
输出结果:
1 : 234
2 : works

extend 继承模版,可以减少大量 html 的重复代码,建立一个 base.html 作为模版,
在其他需要用到的html中直接引入即可,只修改需要改动的地方。

sqlite 数据库

pycharm 默认连接的是sqlite数据库

# 在 setting 中可以看到默认的 databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# 在models文件中添加,创建一张表,
class Book(models.Model):
    name = models.CharField(max_length=20)
    price = models.IntegerField()
    pub_data = models.DateField()

在命令行中输入terminal中 :python manage.py makemigrations 创建表
                          python manage.py migrate

创建成功之后就可以在 pycharm 中连接 sqlite 数据库了

连接上后就可以在视图窗口中修改数据库的数据了

note

表与表之间的关系(两张表)
     一对多
     多对多
     一对一

单表操作  
        表记录的添加
        方式一:
            Book()
            b=Book(name="python基础",price=99,author="libai",pub_date="2017-12-12")
            b.save()
        方式二:
            Book.objects.create()
            Book.objects.create(name="老男孩linux",price=78,author="oldboy",pub_date="2016-12-12")

        表记录的修改
        方式一:
            b=Book.objects.get(author="oldboy")
            b.price=120
            b.save()
        方式二:
            #update是QuerySet
            Book.objects.filter(author="yuan").update(price=999)
         
        表记录的删除:
            Book.objects.filter(author="oldboy").delete()
            
        表记录的查询:
                book_list = Book.objects.filter(id=2)
                book_list=Book.objects.exclude(author="yuan").values("name","price")
                book_list=Book.objects.all()
                book_list = Book.objects.all()[::2]
                book_list = Book.objects.all()[::-1]
                
                #first,last,get取到的是一个实例对象,并非一个QuerySet的集合对象
                book_list = Book.objects.first()
                book_list = Book.objects.last()  
                book_list = Book.objects.get(id=2)#只能取出一条记录时才不报错
                
                ret1=Book.objects.filter(author="oldboy").values("name") #只取出字段为name的值
                ret2=Book.objects.filter(author="yuan").values_list("name","price")           

                book_list= Book.objects.all().values("name").distinct()
                book_count= Book.objects.all().values("name").distinct().count()
               
                模糊查询  双下划线__
                book_list=Book.objects.filter(name__icontains="P").values_list("name","price")
                book_list=Book.objects.filter(id__gt=5).values_list("name","price")
                
      多表操作(一对多):
               添加记录
               #publish_id=2
               Book.objects.create(name="linux运维",price=77,pub_date="2017-12-12",publish_id=2)
               
               #publish=object
               Book.objects.create(name="GO",price=23,pub_date="2017-05-12",publish=publish_obj)
               
               查询记录(通过对象)
                     正向查询:
                     book_obj=Book.objects.get(name="python")   
                     pub_obj=book_obj.publish----》书籍对象对应的出版社对象
                     pub_obj.name
                     反向查询:
                     pub_obj = Publish.objects.filter(name="人民出版社")[0]
                     pub_obj.book_set.all().values("name","price")
                     
               查询记录(filter values  双下划线__)
                    人民出版社出版过的书籍与价格
                    ret=Book.objects.filter(publish__name="人民出版社").values("name","price")
                    python这本书出版社的名字
                    ret2=Publish.objects.filter(book__name="python").values("name")
                    python这本书出版社的名字
                    ret3=Book.objects.filter(name="python").values("publish__name")
                    北京的出版社出版书的名字
                    ret4=Book.objects.filter(publish__city="北京").values("name")
                    2017年上半年出版过书的出版社的名字
                    ret5=Book.objects.filter(pub_date__lt="2017-07-01",pub_date__gt="2017-01-01").values("publish__name")
                    
     多表操作(多对多): 
                创建多对多的关系 author= models.ManyToManyField("Author")
                书籍对象它的所有关联作者  obj=book_obj.authors.all()
                   绑定多对多的关系  obj.add(*QuerySet)   
                                    obj.remove(author_obj)
                 
                如果想向第三张表插入值的方式绑定关系:  手动创建第三张表
                    # class Book_Author(models.Model):
                    # book=models.ForeignKey("Book")
                    # author=models.ForeignKey("Author")                    
                    Book_Author.objects.create(book_id=2,author_id=3)


1.Cookie操作
    - 客户端本地存储的键值对,每次请求浏览器都会带上cookie去访问
    - 确认身份
2.Session操作
    - 保存在服务器端的键值对,客户端会获得一个sessionid来标识,获取数据
3.URL路由
    - /index    ->    views.函数

4.MTV

5.View中返回方式
    - HttpResponse("内容")
    - render(request,'模版路径',{ })
    - redirect('URL')
6.启动
    python manage.py runserver
7.创建project
    django-admin startproject [project名称]
    python manage.py startapp [app名称]
8.URL中有别名
    [
        ('/index/(\d+)', func, name='xxoo')
    ]
9.setting.py 配置
    STATICFILES_DIRS=(
        os.path.join(BASE_DIR,'static'),
    )
10.模版
    {{ 变量 }}
    {% for, if, %}

    views.py
        def func(request):
            return render(request, 'index.html',{'arg':[1,2,4,5,6]})
    index.html

    {{ arg.2 }} 取第三个元素

11.数据库连接修改MySQL
    默认:MySQLDB
    python 3 要修改成pymysql

12.模版继承
    block
    extends
    一个模版可以被多个子模版继承

13.request参数
    - request.method
    - request.GET
    - request.POST.get
    - request.POST.getlist('hobby')

14.外键

15.操作数据表
    python manage.py makemigrations
    python manage.py migrate

16.在html中使用别名指代静态文件路径

17.路由分发

18.数据操作
    models.Tb.objects.all().delete()
    models.Tb.objects.filter(条件).delete()

19.外键的添加
    calss A(models.Model): 部门表
        name = c.CharField(max_length=16,null=True,blank=True)
        //black是admin里是否允许输入为空
    class B():
        title = c
        fk = FK(A)
    models.B.object.create(
        title = '1',
        fk = models.A.object.get(id=1)
    )
    
    models.B.object.create(
        title = '1',
        fk_id = 1
    )   

20.外键关联删除

21.URL匹配
    [
        ('/index/(?P<nid>\d+)'),func
    ]
    views.py
        def func(request,nid):
            pass
22.ORM
    -Models中操作
    - shell操作

    对象 = models.Tb.object.get(id=1)
    [对象,] = models.Tb.object.filter(id=1)

23.CSRF

24.自定义标签

25.XSS攻击

    views.py
        def func(request,nid):
            return render(request,'x.html',{'k1':'v1','k2':'<h1>v2</h1>'})
    x.html
        {{ k1 }}
        {{ k2 }}
        页面输出:
        v1
        <h1>v2</h1>
        
        {{ k1 }}
        {{ k2|safe }}
        页面输出:
        v1
        v2(加大加粗)

26.obj = models.Tb.objects.get(id=1)
   obj.name = '新名称'
   obj.save()

   models.Tb.objects.filter(id=1).update(name="新名称")

27.多表查询 双下划线跨表查询

28.URL,namespace

30.迭代器

31.数据传递中,来回的都是字符串


django 的请求生命周期
    也就是用户从URL访问服务器后发生的一系列事件
    request.GET 就是在请求头中的URL中获取数据,转成字典形式
    request.POST 把请求体中的字符串转换成字典

urls.py 文件的正则匹配,要加$完整匹配


-请求响应Http
    1.发送Http请求
    2.服务器接收,根据请求头中的URL在路由关系表中进行匹配(从上到下)
    3.匹配成功后,执行指定的views函数
        URL -》 函数  ==》 FBV
        URL -》 类    ==》 CBV
  视图函数可以用function,也可以用类方法来接收,使用类,就要继承django为我们提供的父类,URL路由导航也要有所更改
  #urls.py 中
    path('CBV/', views.CBV.as_view()),
  #views.py 中
from django.views import View
class CBV(View): // 继承 View 后,method为GET就会自动调用get方法,post类似
    def get(self,request):
    根据请求头中的 request.method 进行自动执行
        return HttpResponse("CBV.get")
    def post(self,request):
        return HttpResponse("CBV.post")
  在父类 View 中封装了dispatch方法,URL路由传递过来的URL和method首先会传到dispatch中,
  用反射找到我们自定制的方法并执行。

用类方法来处理URL路由过来的事件,事件传递过来首先触发的是dispatch方法,可以在此处对 get 和 post 做日志记录等

from django.views import View
class CBV(View):
    def dispatch(self, request, *args, **kwargs):
        print('dispatch....')
        ret = super(CBV,self).dispatch(request, *args, **kwargs)
        return ret
    def get(self,request):
        return HttpResponse("CBV.get")
    def post(self,request):
        return HttpResponse("CBV.post")

get和post方法在返回过程中,可以添加响应头,返回给客户端

def post(self,request):
    ret = HttpResponse("CBV.post")
    ret['c1'] = 'v2'
    ret.set_cookie('c2', 'v2')
    return ret

在 filter, value, 条件中,外键如果要跨表查询,必须把 . 改为 __,可以跨多张表查询

# cs 为外键
# models.Student.objects.filter(cs.id = nid).delete() 这样不行,必须改为
models.Student.objects.filter(cs__id = nid).delete() 

django 练习的一个在页面上对数据库的操作,文件太多,不好全发上来,只记录一些重要的,

# models.py 表格文件
from django.db import models

# Create your models here.

class Classes(models.Model):
    title = models.CharField(max_length=32)
    m = models.ManyToManyField("Teacher")

class Teacher(models.Model):
    name = models.CharField(max_length=32)

class Student(models.Model):
    username = models.CharField(max_length=32)
    age = models.IntegerField()
    gender = models.NullBooleanField()
    cs = models.ForeignKey("Classes",on_delete=models.CASCADE)

下面是 classes 表的操作

# views 文件下的 Classes.py
from django.shortcuts import render,HttpResponse,redirect
from app01 import models

def get_classes(request): # 获取表格数据
    class_list = models.Classes.objects.all()
    for c in class_list:
        print(c.m.all())
    return render(request, "classes.html", {"class":class_list})

def add_classes(request): # 添加数据
    if request.method == "POST":
        title = request.POST.get("title")
        print("title: ",title)
        if title:
            models.Classes.objects.create(title=title, )
            back = "添加成功,你添加的字段为:" + '"'+ title + '"'
        else:
            back = "添加失败,你提交的是空字段。"
        return render(request, "add_classes.html",{"back":back})
    else:
        return render(request, "add_classes.html")

def del_classes(request): # 删除数据
    if request.method == "GET":
        nid = request.GET.get("nid")
        # print("---------------------------",nid)
        # title = models.Classes.objects.filter(id=nid).values("title")[0]["title"]
        # print("title: ", title)
        models.Classes.objects.filter(id=nid).delete()
        # back = "删除 " + nid + "," + title + " 成功。"
        # return HttpResponse(back)
    return redirect("/classes.html")

def edit_classes(request): # 编辑数据
    if request.method == "GET":
        nid = request.GET.get('nid')
        data_list = models.Classes.objects.filter(id=nid)[0]
        return render(request, "edit_classes.html", {"back":data_list})
    elif request.method == "POST":
        title = request.POST.get("title")
        nid = request.POST.get("nid")
        print("title: ", title)
        print("nid: ", nid)
        models.Classes.objects.filter(id=nid).update(title=title)
        return redirect("/classes.html")
    else:
        return redirect("/classes.html")

def set_teachers(request): # 设置
    if request.method == "GET":
        nid = request.GET.get("nid")
        teachers_list = models.Teacher.objects.all().values("id","name")
        select_teachers = models.Classes.objects.filter(id=nid).values_list("m","m__name")
        print(select_teachers)
        select_teachers_id = list(zip(*select_teachers))[0]
        print(select_teachers_id)
        return render(request,"set_teachers.html",
                      {
                          "teachers_list":teachers_list,
                          "select_teachers_id":select_teachers_id,
                          "nid":nid
                      })
    elif request.method == "POST":
        teachers_list = request.POST.getlist("teachers_list")
        nid = request.POST.get("nid")
        print("------------------",teachers_list)
        print(nid)
        ret = models.Classes.objects.filter(id=nid)[0]
        ret.m.set(teachers_list)
        return redirect("/classes.html")
    else:
        return redirect("/classes.html")

def set_class(request): # 相对应的students 表的 ajax 删除
    if request.method == "GET":
        nid = request.GET.get("nid")
        classes_list = models.Classes.objects.all()
        cs = models.Student.objects.filter(id=nid).values("id","cs_id")
        print(classes_list)
        print(cs)
        return  render(request,"set_teachers.html",{
            "nid":nid,
            "classes_list":classes_list,
            "cs":cs
        })

与其相对应的 classes.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .table{
            margin-top: 50px;
            margin-left: 50px;
            color: red;
        }
        a{
            text-decoration: none;
        }
        .add{
            margin-left: 50px;
            margin-top: 50px;
            margin-bottom: -20px;
        }
        .classes{
            float: left;
        }

    </style>
</head>
<body>
    <div class="add">
        <a href="/add_classes.html">添加</a>
    </div>
    <div class="classes">
        <table border="1px" cellpadding="15px" cellspacing="4px" class="table">
            <thead>
                <tr>
                    <th>id</th>
                    <th>班级名称</th>
                    <th>老师</th>
                    <th colspan="4">操作</th>
                </tr>
            </thead>
            <tbody>
               {% for foo in class %}
                    <tr>
                        <th>{{ foo.id }}</th>
                        <th>{{ foo.title }}</th>
                        <th>
                            {% for i in foo.m.all.values %}
                                <span>{{ i.name }}</span>
                            {% endfor %}
                        </th>
                        <th><a href="/del_classes.html/?nid={{ foo.id }}">删除</a></th>
                        <th><a href="/edit_classes.html/?nid={{ foo.id }}">修改</a></th>
                        <th><a href="/set_teachers.html/?nid={{ foo.id }}">分配老师</a></th>
                        <th><a href="/set_class.html/?nid={{ foo.id }}">分配班级</a></th>
                    </tr>
               {% endfor %}
            </tbody>
        </table>
    </div>
</body>
</html>

效果图


students.py 学生表操作

# views 下的 students.py 文件
from django.shortcuts import render,redirect,HttpResponse
from app01 import models

def get_students(request):
    data_list = models.Student.objects.all()
    return render(request, "students.html",{'students':data_list})

def add_student(request):
    if request.method == "GET":
        cs_list = models.Classes.objects.all().values("title","id")
        return render(request, "add_students.html", {"cs_list":cs_list})
    elif request.method == "POST":
        username = request.POST.get("username")
        age = request.POST.get('age')
        gender = request.POST.get('gender')
        cs= request.POST.get('cs')
        models.Student.objects.create(username=username,age=age,gender=gender,cs_id=cs)
        return redirect("/students.html")
    else:
        return redirect("/students.html")

def del_students(request):
    if request.method == "GET":
        nid = request.GET.get('nid')
        models.Student.objects.filter(id=nid).delete()
    return redirect("/students.html")

def edit_students(request):
    if request.method == "GET":
        nid = request.GET.get("nid")
        data_dic = models.Student.objects.filter(id=nid)[0]
        class_dic = models.Classes.objects.all().values("title","id")
        print(class_dic)
        return render(request, "edit_students.html",{"data_dic":data_dic,"class_dic":class_dic})
    elif request.method == "POST":
        nid = request.POST.get("nid")
        username = request.POST.get("useranme")
        gender = request.POST.get("gender")
        age = request.POST.get("age")
        cs = request.POST.get("cs")
        models.Student.objects.filter(id=nid).update(
            username=username,
            gender=gender,
            age=age,
            cs_id=cs
        )
        return  redirect("/students.html")
    else:
        return redirect("/students.html")

students.html 文件,包含了 ajax

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .table{
            margin-top: 50px;
            margin-left: 50px;
            color: red;
        }
        a{
            text-decoration: none;
        }
        .add{
            margin-left: 50px;
            margin-top: 50px;
            margin-bottom: -20px;
        }
        .classes{
            float: left;
        }

    </style>
</head>
<body>
    <div class="add">
        <a href="/add_students.html">添加</a>
    </div>
    <div class="classes">
        <table border="1px" cellpadding="15px" cellspacing="4px" class="table">
            <thead>
                <tr>
                    <th>id</th>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>性别</th>
                    <th>班级</th>
                    <th colspan="3">操作</th>
                </tr>
            </thead>
            <tbody>
               {% for foo in students %}
                    <tr nid="{{ foo.id }}">
                        <th>{{ foo.id }}</th>
                        <th>{{ foo.username }}</th>
                        <th>{{ foo.age }}</th>
                        {% if foo.gender %}
                            <th>男</th>
                        {% else %}
                            <th>女</th>
                        {% endif %}
                        <th>{{ foo.cs.title }}</th>
                        <th><a href="/del_students.html/?nid={{ foo.id }}">删除</a></th>
                        <th><a onclick="ajax_del(this)">Ajax删除</a></th>
                        <th><a href="/edit_students.html/?nid={{ foo.id }}">修改</a></th>
                    </tr>
               {% endfor %}
            </tbody>
        </table>
    </div>
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        function ajax_del(that) {
            var nid = $(that).parent().parent().attr("nid");
            $.ajax({
                url: "/ajax_del.html",
                type: "get",
                data : {"nid":nid},
                success:function (arg) {
                    if (arg == "successful"){
                        console.log(arg);
                        $(that).parent().parent().remove()
                    }else{
                        alert(arg);
                    }
                }
            })
        }
    </script>
</body>
</html>

setting 设置静态文件路径、MySQL数据库,static目录、打印数据库操作日志
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'books',    #你的数据库名称
        'USER': 'root',   #你的数据库用户名
        'PASSWORD': '89828', #你的数据库密码
        'HOST': '', #你的数据库主机,留空默认为localhost
        'PORT': '3306', #你的数据库端口
    }
}

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
    - 所有学生的姓名以及其所在班级名称,QuerySet,也就是列表类型
        stu_list = Student.objects.all()
        select * from tb;
        [obj,obj,obj,obj] 拿到的是对象,对象 obj.name 就可以访问属性
        
        stu_list = Student.objects.all().values("id",'username')
        select id,username from tb;
        [{"id":1,'username':'xx'},{id:'',username:''}] value 拿到的是列表内封装的字典   
        
        stu_list = Student.objects.all().values_list("id",'username')
        [(1,'root'), (2,'alex')] value_list 拿到的是列表内封装的元组
         
        
        stu_list = Student.objects.all().values('username',"cs__name") cs__name 跨表查询
        for row in stu_list:
            print(row['username'],row['cs__name']) 遍历 stu_list ,记住,row为字典
        
        stu_list = Student.objects.all().values('username',"cs__titile",“cs__fk__name”)
        
    - 找到3班的所有学生
        Student.objects.filter(cs__name='3班')
        
        obj = Classes.objects.filter(name='3班').first()

    
1. 类代表数据库表
2. 类的对象代指数据库的一行记录
3. FK字段代指关联表中的一行数据(类的对象)
4. 
    - 正向:fk字段  (*****能用正向就用正向) 
    - 反向:小写类名_set(默认)   ==> related_name='ssss'
    假设存在两张表class和student,student的外键fk关联class表,cs = models.ForeignKey(Classes) 
    那么从cs就可以直接指向class表的某个数据,反过来,从class表也可以指向student表,
    所得出的list为student下同一个指定老师的集合,通过obj.student_set.all() ,obj 为所选择的某个class对象
    
    也可以更改默认反向默认查找字段,在 cs = models.ForeignKey(Class,related_name="ssss")
5. 谁是主表?就全部列出其数据
    models.Student.objects.all().values('username', 'cs__titile') 列出所有学生的数据,包括班级
    models.Classes.objects.all().values('titile', 'ssss__username') 列出所有班级的数据,
    values 列出来的数据不为对象,为值
    
4. M2M字段,自动生成第三张表;依赖关联表对第三张表间接操作
    Classes 添加 m = manytomany字段,关联Student
    obj.m.all() 列出关联学生的所有老师
    obj.m.add(3) 添加
    obj.m.set([1,2]) 设置,不为1,2的删除
    在student表中的对象也可以关联
    obj.classes_set.all() 等

对话框添加,删除,修改:
    添加:
        Ajax偷偷向后台发请求:
            1. 下载引入jQuery
            2. 
                $.ajax({
                    url: '/add_classes.html',
                    type: 'POST',
                    data: {'username':'root','password': '123'},
                    success:function(arg){
                        // 回调函数,arg是服务端返回的数据
            // window.location.reload(); JS 主动刷新页面
                    }
                })
      
ajax补充:data: $("#fm").serialize()

django

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容