表关系总结 1. 关于删除 2. 编辑和一对多展示问题 3. 编辑和多对多问题 4. 新增和一对多的问题 5. 新增和多对多的问题 6. 多个对象之间加符号 7.表关系(注意关联字段位置) 4. input 的标签的一些属性 5. form表单中的属性

    pk相当于主键,不用管主键是什么,用pk代替即可                  
前端代码			   <a href="/book_edit/?id={{ all_book.pk }}">编辑</a>
                        <a href="/book_del/?id={{ all_book.pk }}">删除</a>
{#                      <a href="/book_del/?id={{ all_book.id }}">删除</a>#}
{#                        此处一定是要用主键,主键才能查找,或者使用唯一性的值,如果不是唯一,例如书名相同,							那么删除时可能会删除掉多条数据 #}
    
后端代码  		
    def book_del(request):
        pk = request.GET.get("id")
        ret = models.Book.objects.filter(pk=pk)
        # 浏览器界面输入http://127.0.0.1:8000/book_del/?id=180,则ret为空
        if not ret:
            return HttpResponse("数据不存在")
        ret.delete()
        return redirect("book_list")

以删除为例,点击删除按钮,发生两个动作,第一是发送get请求,通过此请求获得要操作的哪一行的id,删除之后再重定向展示页面
表关系总结
1. 关于删除
2. 编辑和一对多展示问题
3. 编辑和多对多问题
4. 新增和一对多的问题
5. 新增和多对多的问题
6. 多个对象之间加符号
7.表关系(注意关联字段位置)
4. input 的标签的一些属性
5. form表单中的属性

表关系总结
1. 关于删除
2. 编辑和一对多展示问题
3. 编辑和多对多问题
4. 新增和一对多的问题
5. 新增和多对多的问题
6. 多个对象之间加符号
7.表关系(注意关联字段位置)
4. input 的标签的一些属性
5. form表单中的属性

2. 编辑和一对多展示问题

1. 编辑的路径问题

​ 写法大致和删除相同,根据唯一固定的id去确定删除哪条数据

<a href="/book_edit/?id={{ all_book.pk }}">编辑</a>

2. 携带原有的数据

为了编辑时保留原有的数据,在标签中需要设置value属性,一条数据时,value="{{ book_obj.title }}",但是有多条数据需要展示时,为了能够确保我们说对应的数据能够选中,假如if判断,满足条件,默认选中,

关于一对多展示的结果,如书籍关联出版社,book_obj.pub 的结果是出版社相对应数据的的model对象

1. 只有一条数据
<input type="text" name="title" value="{{ book_obj.title }}">  
# book_obj 是后端传来的根据id获取的这一条数据的对象
book_obj = models.Book.objects.filter(pk=pk).first()
2. 有多条数据
   <select name="pub_id" class="form-control" >
        {% for publisher_obj in publisher_objs %} #循环展示每一条出版社数据
             {% if book_obj.pub == publisher_obj %}   
            {# 实例对象.关联字段是一个出版社对象和选中的对象相同的出版社信息对象默认选中 #}
                 <option selected value= "{{ publisher_obj.pk }}">{{ publisher_obj.name }}</option>
              {% else %}
                 <option value= "{{ publisher_obj.pk }}">{{ publisher_obj.name }}</option>
              {% endif %}
         {% endfor %}
   </select>

3. 编辑和多对多问题

以作者表关联书籍表为例,字段在作者表,多对多的关系,需创建第三张表,表关系如下:

class Book(models.Model):
    title = models.CharField(max_length=32, unique=True)
    pub = models.ForeignKey('Publisher', on_delete=models.CASCADE)
 	# au = models.ManyToManyField(to="Author")   # to="Author" 用字符串方式可以不必在乎表的顺序
    
class Author(models.Model):
    name = models.CharField(max_length=32)
    books = models.ManyToManyField('Book')  # 不会生成字段  生成第三张表
books属性只是用于创建第三张表,不在Author表中显示,第三张表中结构 id  author_id  book_id

<select name="book_id"  multiple>  // 设置多选
    {% for all_book in all_books %}     // 做判断,默认选中的,循环的每个书籍对象看看哪个在我选择的对象中
         {% if all_book in all_author.books.all %}  // 前段有括号,后端没有括号
             <option selected value="{{ all_book.pk }}">{{ all_book.title }}</option>
         {% else %}
              <option value="{{ all_book.pk }}">{{ all_book.title }}</option>
         {% endif %}
    {% endfor %}
</select>

1. 由作者查书籍 正向

all_authors = models.Author.objects.all()  #获得所有的作者对象列表  queryset类型
for author in all_authors:    #获得每个作者对象
        print(author)        # model对象,实例对象  Author object
        print(author.name)   # 由对象查属性 str类型 
        print(author.books,type(author.books))  # 多对多的关系管理对象 app01.Book.None 不是想要的
        print(author.books.all(),type(author.books.all()))  # 关系对象列表 书籍对象列表 queryset类型

注意查多个书籍对象:作者对象 -- 点属性得到书籍对象 --- 点all()得到所有的书籍对象

2. 由书籍查作者 反向

all_books = models.Book.objects.all()  # 获得所有的书籍对象   queryset类型
for book in all_books:     #获得每个书籍对象
	print(book)  # 书籍对象
	print(book.title)  # 有对象查属性  str 
	print(book.author_set)   # 多对多的关系管理对象
	print(book.author_set.all())   # 书籍关联的所有的作者对象  对象列表   queryset类型

注意查多个作者对象:书籍对象 -- 点小写表名_set得到作者对象 --- 点all()得到所有的作者对象

3. 编辑提交数据 getlist()方法

# 获取提交的数据
author_name = request.POST.get('author_name')
book_id = request.POST.getlist('book_id')     

# 向数据库中提交数据
author_obj.name = author_name
    author_obj.save()
# 设置多对多的关系,向第三张表添加数据
author_obj.books.set(book_id)

#反向 已知书籍对象,向第三张表插入数据   ******************************* 添加
def book_add(request):
    error = ""
    if request.method == "POST":
        title = request.POST.get("title")
        pub_id = request.POST.get("pub_id")
        author_id = request.POST.getlist("author_id")     # 得到作者的id列表
        # print(author_id)

        if not title:
            error = "书名不能为空"
        elif models.Book.objects.filter(title=title):
            error = "书名已存在"
        else:
            ret = models.Book.objects.create(
                title=title,
                pub_id=pub_id)
            # ret.author_set.add(*name)   # 反向插入第三张表  
            ret.author_set.set(author_id)   # 反向插入第三张表  
            return redirect("book_list")

    publisher_objs = models.Publisher.objects.all()
    author_objs = models.Author.objects.all()
    return render(request, "book/book_add01.html", {"author_objs":author_objs,"publisher_objs":publisher_objs, "error":error})

# 对应前端代码
<select name="author_id"  multiple>
        {% for author_obj in author_objs %}
               <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
         {% endfor %}
</select>

#**********************  编辑****************
def book_edit(request):
    error = ""
    pk = request.GET.get("id")
    book_obj = models.Book.objects.filter(pk=pk).first()
    # 浏览器输入127.0.0.1:8000/?id=100
    if not book_obj:
        return HttpResponse("没有此数据")
    elif request.method == "POST":
        title = request.POST.get("title")
        pub_id = request.POST.get("pub_id")
        author_id = request.POST.getlist("author_id")  # 获得作者列表
        if not title:
            error = "书名不能为空"
        elif book_obj.title != title and models.Book.objects.filter(title=title):
            error = "书名已经存在"
        else:
            # print(book_obj.pub)   Publisher object
            # ret = models.Book.objects.filter(pk=pk).updata()
            # print(ret)
            book_obj.title = title
            book_obj.pub_id = pub_id
            book_obj.save()
            book_obj.author_set.set(author_id)  # 反向插入第三张表
            return redirect("book_list")

    publisher_objs = models.Publisher.objects.all()
    author_objs = models.Author.objects.all()    # 获得所有的作者对象
    return render(request, "book/book_edit01.html", {"author_objs":author_objs,"book_obj":book_obj, "publisher_objs":publisher_objs, "error":error})

# 前端代码
<select name="author_id" >
     {% for author_obj in author_objs %}  # author_obj 循环的每一个作者对象
           {% if author_obj in book_obj.author_set.all %}  # 默认条件下作者对象,在就默认选中
                 <option selected value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
           {% else %}
                  <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
            {% endif %}
       {% endfor %}
</select>

4. 新增和一对多的问题

title = request.POST.get("title")  
pub_id = request.POST.get("pub_id")  
models.Book.objects.create(
    title=title,
    pub_id=pub_id)  # pub对应对象   pub_id对应id值

5. 新增和多对多的问题

author_name = request.POST.get('author_name')
book_id = request.POST.getlist('book_id') # getlist() 方法,得到书籍id列表  get方法只能得到最后一个数据

# 向数据库插入数据
author_obj = models.Author.objects.create(name=author_name)
# 设置多对多的关系,向第三张表添加数据
author_obj.books.set(book_id)    # 用set向第三张表中添加数据
#author_obj.books.add(*book_id)    # 用set向第三张表中添加数据

# ********************** 正向添加************************
def author_add(request):
	 error = ""
    all_author = models.Author.objects.all().first()
    all_books = models.Book.objects.all()
    if request.method == "POST":
        name = request.POST.get("name")
        book_id = request.POST.getlist("book_id") # 获取所有的书籍id
        if not name:
            error = "作者名不能为空"
        elif all_author.name == name:
            error = "作者已经存在"
        else:
            author_obj = models.Author.objects.create(name=name)  # model 对象
            print(author_obj)
            author_obj.books.set(book_id)
            return redirect("author_list")
    return render(request, "author/author_add.html", {"all_books":all_books, "error":error})
# 前端代码
<select name="book_id" > // 设置多选
     {% for all_book in all_books %}
           <option value="{{ all_book.pk }}">{{ all_book.title }}</option>
     {% endfor %}
</select>

# **************************正向编辑********************
def author_edit(request):
	    error = ""
    pk = request.GET.get("id")
    all_author = models.Author.objects.filter(pk=pk).first()
    all_books = models.Book.objects.all()
    if not all_author:
        return HttpResponse("数据不存在")
    elif request.method == "POST":
        name = request.POST.get("name")
        book_id = request.POST.getlist("book_id")
        if not name:
            error = "作者不能为空"
        elif all_author.name != name and models.Author.objects.filter(name=name):
            error = "作者已经存在"
        else:
            all_author.name = name
            all_author.save()
            all_author.books.set(book_id)  # 向第三张表插入数据
            return redirect("author_list")
    return render(request, "author/author_edit.html", {"all_books":all_books, "all_author":all_author, "error":error})

#**前端代码
<select name="book_id" >  // 设置多选
    {% for all_book in all_books %}  # 展示所有的书籍对象
         {% if all_book in all_author.books.all %}  # 查看对象是否在默认的对象中
              <option selected value="{{ all_book.pk }}">{{ all_book.title }}</option>
         {% else %}
              <option value="{{ all_book.pk }}">{{ all_book.title }}</option>
         {% endif %}
     {% endfor %}
</select>

6. 多个对象之间加符号

<td>
   {% for all_book in all_author.books.all %}
         《{{ all_book.title }}》 # 展示书籍
              {% if forloop.last %}  # 如果是最后一个什么也不加
               {% else %}  # 如果不是,加逗号
                 ,
               {% endif %}
   {% endfor %}
</td>

7.表关系(注意关联字段位置)

from django.db import models

# Create your models here.
class Publisher(models.Model):
    pid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)

class Book(models.Model):

    title = models.CharField(max_length=32,unique=True)
    pub = models.ForeignKey(to="Publisher",on_delete=models.CASCADE)
    # au = models.ManyToManyField(to="Author")   # to="Author" 用字符串方式可以不必在乎表的顺序

class Author(models.Model):

    name = models.CharField(max_length=32)
    books = models.ManyToManyField(to=Book)  # 多对多关系  

4. input 的标签的一些属性

placeholder = "用户名"   设置标签中的默认内容
autocomplete = "off"     关闭历史输入内容
oncontextmenu = "return false"   右键点击时无效
onpaste = "return false"   禁止粘贴 一般用在需要输密码的属性
value = {{ publisher_obj.name }}   属性的作用是携带已有的数据
name = "name"  的作用是携带写入的数据

5. form表单中的属性

novalidate = "novalidate"     告诉浏览器关闭验证