DAY17-Django之model增删改

添加表记录

普通字段

#方式1
publish_obj=Publish(name="人民出版社",city="北京",email="renMin@163.com")
publish_obj.save() # 将数据保存到数据库

#方式2   返回值publish_obj是添加的记录对象
publish_obj=Publish.objects.create(name="人民出版社",city="北京",email="renMin@163.com")

#方式3   
表.objects.create(**request.POST.dict())
#括号内可以使用字典类型数据 **kwargs,不过要先把request.POST.dict()中不相关的键值对pop掉

外键字段

#方式1:外键=父表的对象
   publish_obj=Publish.objects.get(nid=1)
   Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=665,pageNum=334,publish=publish_obj)
 
#方式2:外键_id=父表的id字段
   Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=665,pageNum=334,publish_id=1)

 关键点:book_obj.publish是什么?是被关联的记录对象

多对多字段

book_obj=Book.objects.create(title="追风筝的人",publishDate="2012-11-12",price=69,pageNum=314,publish_id=1)
 
author_yuan=Author.objects.create(name="yuan",age=23,authorDetail_id=1)
author_egon=Author.objects.create(name="egon",age=32,authorDetail_id=2)
 
book_obj.authors.add(author_egon,author_yuan)    #  将某个特定的 model 对象添加到被关联对象集合中,可以是对象也可以是被关联表记录id   =======    book_obj.authors.add(*[])
 
book_obj.authors.create()      #创建并保存一个新对象,然后将这个对象加被关联对象的集合中,然后返回这个新对象。

 关键点:book_obj.authors是什么?是被关联的记录对象集合

解除关系:

book_obj.authors.remove()     # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
book_obj.authors.clear()       #清空被关联对象集合。

 

class RelatedManager

"关联管理器"是在一对多或者多对多的关联上下文中使用的管理器。它存在于下面两种情况:

ForeignKey关系的“另一边”。像这样:

from django.db import models
 
class Reporter(models.Model):
    # ...
    pass
 
class Article(models.Model):
    reporter = models.ForeignKey(Reporter)

在上面的例子中,管理器reporter.article_set拥有下面的方法。

ManyToManyField关系的两边:

class Topping(models.Model):
    # ...
    pass
 
class Pizza(models.Model):
    toppings = models.ManyToManyField(Topping)

这个例子中,topping.pizza_set 和pizza.toppings都拥有下面的方法。

add(obj1[, obj2, ...])

把指定的模型对象添加到关联对象集中。

例如:

>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
在上面的例子中,对于ForeignKey关系,e.save()由关联管理器调用,执行更新操作。然而,在多对多关系中使用add()并不会调用任何 save()方法,而是由QuerySet.bulk_create()创建关系。

延伸:

# 1 *[]的使用
>>> book_obj = Book.objects.get(id=1)
>>> author_list = Author.objects.filter(id__gt=2)
>>> book_obj.authors.add(*author_list)


# 2 直接绑定主键
book_obj.authors.add(*[1,3])  # 将id=1和id=3的作者对象添加到这本书的作者集合中
                              # 应用: 添加或者编辑时,提交作者信息时可以用到.

create(**kwargs)

创建一个新的对象,保存对象,并将它添加到关联对象集之中。返回新创建的对象:

>>> b = Blog.objects.get(id=1)
>>> e = b.entry_set.create(
...     headline='Hello',
...     body_text='Hi',
...     pub_date=datetime.date(2005, 1, 1)
... )

# No need to call e.save() at this point -- it's already been saved.
这完全等价于(不过更加简洁于):

>>> b = Blog.objects.get(id=1)
>>> e = Entry(
...     blog=b,
...     headline='Hello',
...     body_text='Hi',
...     pub_date=datetime.date(2005, 1, 1)
... )
>>> e.save(force_insert=True)
要注意我们并不需要指定模型中用于定义关系的关键词参数。在上面的例子中,我们并没有传入blog参数给create()。Django会明白新的 Entry对象blog 应该添加到b中。

remove(obj1[, obj2, ...])

从关联对象集中移除执行的模型对象:

>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
对于ForeignKey对象,这个方法仅在null=True时存在。

clear()

从关联对象集中移除一切对象。

>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
注意这样不会删除对象 —— 只会删除他们之间的关联。

就像 remove() 方法一样,clear()只能在 null=True的ForeignKey上被调用。

set()方法

先清空,在设置,编辑书籍时即可用到

注意

对于所有类型的关联字段,add()、create()、remove()和clear(),set()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

直接赋值:

通过赋值一个新的可迭代的对象,关联对象集可以被整体替换掉。

>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list

如果外键关系满足null=True,关联管理器会在添加new_list中的内容之前,首先调用clear()方法来解除关联集中一切已存在对象的关联。否则, new_list中的对象会在已存在的关联的基础上被添加。

修改表记录

注意:

<1> 第二种方式修改不能用get的原因是:update是QuerySet对象的方法,get返回的是一个model对象,它没有update方法,而filter返回的是一个QuerySet对象(filter里面的条件可能有多个条件符合,比如name='alvin',可能有两个name='alvin'的行数据)。

<2>在“插入和更新数据”小节中,我们有提到模型的save()方法,这个方法会更新一行里的所有列。 而某些情况下,我们只需要更新行里的某几列。

 

此外,update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。

注意,这里因为update返回的是一个整形,所以没法用query属性;对于每次创建一个对象,想显示对应的raw sql,需要在settings加上日志记录部分

删除表记录

删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:

e.delete()

你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

例如,下面的代码将删除 pub_date 是2005年的 Entry 对象:

Entry.objects.filter(pub_date__year=2005).delete()
b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()

 

要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

Entry.objects.all().delete()

如果不想级联删除,可以设置为:

pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)

 

posted @ 2018-04-30 16:00  guoyunlong666  阅读(158)  评论(0编辑  收藏  举报