天天看点

Python全栈之路系列之Django模型续

在<code>app</code>的models.py文件内添加以下内容用户创建一对多关系的表:

<code>from</code> <code>django.db </code><code>import</code> <code>models</code>

<code># Create your models here.</code>

<code>class</code> <code>UserType(models.Model):</code>

<code>    </code><code>nid </code><code>=</code> <code>models.AutoField(primary_key</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>caption </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>32</code><code>)</code>

<code>    </code> 

<code>class</code> <code>UserInfo(models.Model):</code>

<code>    </code><code>username </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>32</code><code>)</code>

<code>    </code><code>password </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>16</code><code>)</code>

<code>    </code><code>user_type </code><code>=</code> <code>models.ForeignKey(</code><code>'UserType'</code><code>)</code>

把<code>app</code>的名字添加到项目的<code>settings.py</code>配置文件的INSTALLED_APPS中,然后再数据库中生成表:

<code>E:\DjangoProjects&gt;python manage.py makemigrations</code>

<code>E:\DjangoProjects&gt;python manage.py migrate</code>

进入带有django环境变量的项目,然后把模型导入进去,用于做下面的操作

<code>E:\DjangoProjects&gt;python manage.py shell</code>

<code>Python </code><code>3.5</code><code>.</code><code>2</code> <code>(v3.</code><code>5.2</code><code>:</code><code>4def2a2901a5</code><code>, Jun </code><code>25</code> <code>2016</code><code>, </code><code>22</code><code>:</code><code>18</code><code>:</code><code>55</code><code>) [MSC v.</code><code>1900</code> <code>64</code> <code>bit (AMD64)] on win32</code>

<code>Type</code> <code>"help"</code><code>, </code><code>"copyright"</code><code>, </code><code>"credits"</code> <code>or</code> <code>"license"</code> <code>for</code> <code>more information.</code>

<code>(InteractiveConsole)</code>

<code>&gt;&gt;&gt; </code><code>from</code> <code>app01 </code><code>import</code> <code>models</code>

添加数据

<code># 通过create方式进行数据的添加</code>

<code>&gt;&gt;&gt; models.UserType.objects.create(caption</code><code>=</code><code>'版主'</code><code>)</code>

<code>&lt;UserType: UserType </code><code>object</code><code>&gt;</code>

<code># 通过save保存的方式添加数据</code>

<code>&gt;&gt;&gt; obj </code><code>=</code> <code>models.UserType(caption</code><code>=</code><code>'管理员'</code><code>)</code>

<code>&gt;&gt;&gt; obj.save()</code>

<code># 通过字典的方式进行数据添加</code>

<code>&gt;&gt;&gt; UserInfoDict </code><code>=</code> <code>{</code><code>'username'</code><code>:</code><code>'ansheng'</code><code>,</code><code>'password'</code><code>:</code><code>'helloword'</code><code>,</code><code>'user_type'</code><code>: models.UserType.objects.get(nid</code><code>=</code><code>1</code><code>)}</code>

<code># 通过**UserInfoDict把数据以字典方式传给create</code>

<code>&gt;&gt;&gt; models.UserInfo.objects.create(</code><code>*</code><code>*</code><code>UserInfoDict)</code>

<code>&lt;UserInfo: UserInfo </code><code>object</code><code>&gt;</code>

<code>&gt;&gt;&gt; UserInfoDict </code><code>=</code> <code>{</code><code>'username'</code><code>:</code><code>'hello'</code><code>,</code><code>'password'</code><code>:</code><code>'word'</code><code>,</code><code>'user_type'</code><code>: models.UserType.objects.get(nid</code><code>=</code><code>2</code><code>)}</code>

<code># 如果知道user_type_id代表多少,那么也可以直接写数字</code>

<code>&gt;&gt;&gt; UserInfoDict </code><code>=</code> <code>{</code><code>'username'</code><code>:</code><code>'ansheng'</code><code>,</code><code>'password'</code><code>:</code><code>'helloword'</code><code>,</code><code>'user_type_id'</code><code>: </code><code>2</code><code>}</code>

修改数据

<code># 指定条件更新</code>

<code>&gt;&gt;&gt; models.UserInfo.objects.</code><code>filter</code><code>(password</code><code>=</code><code>'helloword'</code><code>).update(password</code><code>=</code><code>'hw'</code><code>)</code>

<code>1</code>

<code># 获取id=1的这条数据对象</code>

<code>&gt;&gt;&gt; obj </code><code>=</code> <code>models.UserInfo.objects.get(</code><code>id</code><code>=</code><code>1</code><code>)</code>

<code># 把username字段修改成as</code>

<code>&gt;&gt;&gt; obj.username </code><code>=</code> <code>'as'</code>

<code># 保存操作</code>

删除数据

<code>&gt;&gt;&gt; models.UserInfo.objects.</code><code>filter</code><code>(username</code><code>=</code><code>'ansheng'</code><code>, user_type_id</code><code>=</code><code>'2'</code><code>).delete()</code>

<code>(</code><code>1</code><code>, {</code><code>'app01.UserInfo'</code><code>: </code><code>1</code><code>})</code>

查询数据

<code># 获取单条数据,不存在则报错</code>

<code>&gt;&gt;&gt; models.UserInfo.objects.get(</code><code>id</code><code>=</code><code>1</code><code>)</code>

<code>&gt;&gt;&gt; models.UserInfo.objects.get(</code><code>id</code><code>=</code><code>23</code><code>)</code>

<code>Traceback (most recent call last):</code>

<code>  </code><code>File</code> <code>"&lt;console&gt;"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code>&lt;module&gt;</code>

<code>  </code><code>File</code> <code>"C:\Python\Python35\lib\site-packages\django\db\models\manager.py"</code><code>, line </code><code>85</code><code>, </code><code>in</code> <code>manager_method</code>

<code>    </code><code>return</code> <code>getattr</code><code>(</code><code>self</code><code>.get_queryset(), name)(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>

<code>  </code><code>File</code> <code>"C:\Python\Python35\lib\site-packages\django\db\models\query.py"</code><code>, line </code><code>385</code><code>, </code><code>in</code> <code>get</code>

<code>    </code><code>self</code><code>.model._meta.object_name</code>

<code>app01.models.DoesNotExist: UserInfo matching query does </code><code>not</code> <code>exist.</code>

<code># 获取全部数据</code>

<code>&gt;&gt;&gt; models.UserInfo.objects.</code><code>all</code><code>()</code>

<code>&lt;QuerySet [&lt;UserInfo: UserInfo </code><code>object</code><code>&gt;]&gt;</code>

<code># 获取指定条件的数据</code>

<code>&gt;&gt;&gt; models.UserInfo.objects.</code><code>filter</code><code>(username</code><code>=</code><code>'as'</code><code>)</code>

查询出来的结果都是queryset对象

query方法

query是用来查看查询语句的,即django生成的SQL

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserType.objects.</code><code>all</code><code>()</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(ret.query)</code>

<code>SELECT `app01_usertype`.`nid`, `app01_usertype`.`caption` FROM `app01_usertype`</code>

values与values_list

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserType.objects.</code><code>all</code><code>().values(</code><code>'nid'</code><code>)</code>

<code># 返回的列表,列表里面套字典</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>type</code><code>(ret),ret)</code>

<code>&lt;</code><code>class</code> <code>'django.db.models.query.QuerySet'</code><code>&gt; &lt;QuerySet [{</code><code>'nid'</code><code>: </code><code>1</code><code>}, {</code><code>'nid'</code><code>: </code><code>2</code><code>}]&gt;</code>

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserType.objects.</code><code>all</code><code>().values_list(</code><code>'nid'</code><code>)</code>

<code># 返回一个列表,列表里面套集合</code>

<code>&lt;</code><code>class</code> <code>'django.db.models.query.QuerySet'</code><code>&gt; &lt;QuerySet [(</code><code>1</code><code>,), (</code><code>2</code><code>,)]&gt;</code>

双下划线连表操作

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserInfo.objects.</code><code>all</code><code>().values(</code><code>'username'</code><code>,</code><code>'user_type__caption'</code><code>)</code>

<code># INNER</code>

<code>SELECT `app01_userinfo`.`username`, `app01_usertype`.`caption` FROM `app01_userinfo` INNER JOIN `app01_usertype` ON (`app01_userinfo`.`user_type_id` </code><code>=</code> <code>`app01_usertype`.`nid`)</code>

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserInfo.objects.</code><code>all</code><code>()</code>

<code>&gt;&gt;&gt; </code><code>for</code> <code>item </code><code>in</code> <code>ret:</code>

<code>...  </code><code>print</code><code>(item,item.</code><code>id</code><code>,item.user_type.nid,item.user_type.caption,item.user_type_id)</code>

<code>...</code>

<code>UserInfo </code><code>object</code> <code>1</code> <code>1</code> <code>版主 </code><code>1</code>

获取用户类型是超级管理员的所有用户

正向查找

通过双下划线连表查询

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserInfo.objects.</code><code>filter</code><code>(user_type__caption </code><code>=</code> <code>"管理员"</code><code>).values(</code><code>'username'</code><code>,</code><code>'user_type__caption'</code><code>)</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(ret,</code><code>type</code><code>(ret),ret.query)</code>

<code>&lt;QuerySet [{</code><code>'user_type__caption'</code><code>: </code><code>'管理员'</code><code>, </code><code>'username'</code><code>: </code><code>'hello'</code><code>}]&gt; &lt;</code><code>class</code> <code>'django.db.models.query.QuerySet'</code><code>&gt; SELECT `app01_userinfo`.`username`, `app01_usertype`.`caption` FROM `app01_userinfo` INNER JOIN `app01_usertype` ON (`app01_userinfo`.`user_type_id` </code><code>=</code> <code>`app01_usertype`.`nid`) WHERE `app01_usertype`.`caption` </code><code>=</code> <code>管理员</code>

反向查找

先查找UserType表中数据,再把这个数据和UserInfo表中进行过滤

<code>&gt;&gt;&gt; obj </code><code>=</code> <code>models.UserType.objects.</code><code>filter</code><code>(caption</code><code>=</code> <code>'管理员'</code><code>).first()</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(obj.nid, obj.caption)</code>

<code>2</code> <code>管理员</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(obj.userinfo_set.</code><code>all</code><code>())</code>

把UserType表里的所有字段和userinfo表进行一个匹配,如果有匹配到就显示出来

<code>&gt;&gt;&gt; ret </code><code>=</code> <code>models.UserType.objects.</code><code>all</code><code>().values(</code><code>'nid'</code><code>,</code><code>'caption'</code><code>,</code><code>'userinfo__username'</code><code>)</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(ret)</code>

<code>&lt;QuerySet [{</code><code>'userinfo__username'</code><code>: </code><code>'as'</code><code>, </code><code>'nid'</code><code>: </code><code>1</code><code>, </code><code>'caption'</code><code>: </code><code>'版主'</code><code>}, {</code><code>'userinfo__username'</code><code>: </code><code>'hello'</code><code>, </code><code>'nid'</code><code>: </code><code>2</code><code>, </code><code>'caption'</code><code>: </code><code>'管理员'</code><code>}]&gt;</code>

两种创建多对多表的方式

手动指定第三张表进行创建

<code>class</code> <code>HostGroup(models.Model):</code>

<code>    </code><code>hgid </code><code>=</code> <code>models.AutoField(primary_key</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>host_id </code><code>=</code> <code>models.ForeignKey(</code><code>'Host'</code><code>)</code>

<code>    </code><code>group_id </code><code>=</code> <code>models.ForeignKey(</code><code>'Group'</code><code>)</code>

<code>class</code> <code>Host(models.Model):</code>

<code>    </code><code>hid </code><code>=</code> <code>models.AutoField(primary_key</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>hostname </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>32</code><code>)</code>

<code>    </code><code>ip </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>32</code><code>)</code>

<code>class</code> <code>Group(models.Model):</code>

<code>    </code><code>gid </code><code>=</code> <code>models.AutoField(primary_key</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>name </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>16</code><code>)</code>

<code>    </code><code># 指定第三张表</code>

<code>    </code><code>h2g </code><code>=</code> <code>models.ManyToManyField(</code><code>'Host'</code><code>, through</code><code>=</code><code>'HostGroup'</code><code>)</code>

django帮我们创建第三张表

创建以下表关系用于测试多对多

<code>    </code><code># 任意一个字段,会自动生成第三张表,且第三张表会自动的添加联合唯一索引,Unique</code>

<code>    </code><code>h2g </code><code>=</code> <code>models.ManyToManyField(</code><code>'Host'</code><code>)</code>

插入以下数据用于测试

<code># Host插入数据</code>

<code>&gt;&gt;&gt; models.Host.objects.create(hostname</code><code>=</code><code>'localhost'</code><code>, ip</code><code>=</code><code>'192.168.1.1'</code><code>)</code>

<code>&lt;Host: Host </code><code>object</code><code>&gt;</code>

<code>&gt;&gt;&gt; models.Host.objects.create(hostname</code><code>=</code><code>'linux-node1'</code><code>, ip</code><code>=</code><code>'192.168.1.2'</code><code>)</code>

<code>&gt;&gt;&gt; models.Host.objects.create(hostname</code><code>=</code><code>'linux-node2'</code><code>, ip</code><code>=</code><code>'192.168.1.3'</code><code>)</code>

<code>&gt;&gt;&gt; models.Host.objects.create(hostname</code><code>=</code><code>'web-node1'</code><code>, ip</code><code>=</code><code>'192.168.1.4'</code><code>)</code>

<code># Group插入数据</code>

<code>&gt;&gt;&gt; models.Group.objects.create(name</code><code>=</code><code>'市场部'</code><code>)</code>

<code>&lt;Group: Group </code><code>object</code><code>&gt;</code>

<code>&gt;&gt;&gt; models.Group.objects.create(name</code><code>=</code><code>'技术部'</code><code>)</code>

<code>&gt;&gt;&gt; models.Group.objects.create(name</code><code>=</code><code>'财务部'</code><code>)</code>

<code>&gt;&gt;&gt; models.Group.objects.create(name</code><code>=</code><code>'运维部'</code><code>)</code>

<code>&gt;&gt;&gt; models.Group.objects.create(name</code><code>=</code><code>'销售部'</code><code>)</code>

单个添加数据

<code># 获取组中gid=1的这条数据</code>

<code>&gt;&gt;&gt; obj </code><code>=</code> <code>models.Group.objects.get(gid</code><code>=</code><code>1</code><code>)</code>

<code># 获取表中的内容</code>

<code>&gt;&gt;&gt; obj.gid, obj.name</code>

<code>(</code><code>1</code><code>, </code><code>'市场部'</code><code>)</code>

<code># 获取第三张表的内容</code>

<code>&gt;&gt;&gt; obj.h2g.</code><code>all</code><code>()</code>

<code>&lt;QuerySet []&gt;</code>

<code># 获取一个主机</code>

<code>&gt;&gt;&gt; h1 </code><code>=</code> <code>models.Host.objects.get(hid</code><code>=</code><code>2</code><code>)</code>

<code># 获取主机的IP</code>

<code>&gt;&gt;&gt; h1.ip</code>

<code>'192.168.1.2'</code>

<code># 把主机hid=2和组gid=1的这两条数据做一个对应关系,放入第三章比哦中</code>

<code>&gt;&gt;&gt; obj.h2g.add(h1)</code>

<code># 查看输入</code>

<code>&lt;QuerySet [&lt;Host: Host </code><code>object</code><code>&gt;]&gt;</code>

批量添加

<code># 获取GID大于2的所有主机</code>

<code>&gt;&gt;&gt; h </code><code>=</code> <code>models.Host.objects.</code><code>filter</code><code>(hid__gt</code><code>=</code><code>2</code><code>)</code>

<code># 获取到两条数据</code>

<code>&gt;&gt;&gt; h</code>

<code>&lt;QuerySet [&lt;Host: Host </code><code>object</code><code>&gt;, &lt;Host: Host </code><code>object</code><code>&gt;]&gt;</code>

<code># 把上面的主机添加到第三张表内</code>

<code>&gt;&gt;&gt; obj.h2g.add(</code><code>*</code><code>h)</code>

<code># 添加的数据总和为三条</code>

<code>&lt;QuerySet [&lt;Host: Host </code><code>object</code><code>&gt;, &lt;Host: Host </code><code>object</code><code>&gt;, &lt;Host: Host </code><code>object</code><code>&gt;]&gt;</code>

反向操作

上面的例子中我们往一个部门中添加了多台机器,那么现在我们将一个机器添加到多个部门中

<code># 获取ip='192.168.1.3'的这台机器</code>

<code>&gt;&gt;&gt; host </code><code>=</code> <code>models.Host.objects.get(ip</code><code>=</code><code>'192.168.1.3'</code><code>)</code>

<code># 把上面的那台机器添加到gid大于2的所有部门内</code>

<code>&gt;&gt;&gt; host.group_set.add(</code><code>*</code><code>models.Group.objects.</code><code>filter</code><code>(gid__gt</code><code>=</code><code>2</code><code>))</code>

remove()

<code># 删除在关系表中gid=3的这条数据</code>

<code>&gt;&gt;&gt; host.group_set.remove(</code><code>*</code><code>models.Group.objects.</code><code>filter</code><code>(gid</code><code>=</code><code>3</code><code>))</code>

delete()

<code># 原始数据和关系表中的数据都删除</code>

<code>&gt;&gt;&gt; host.group_set.</code><code>all</code><code>().delete()</code>

<code># 总影响行数8,在app01.Group内删除了3条,在app01.Group_h2g删除了5条</code>

<code>(</code><code>8</code><code>, {</code><code>'app01.Group'</code><code>: </code><code>3</code><code>, </code><code>'app01.Group_h2g'</code><code>: </code><code>5</code><code>})</code>

为了不影响后面的测试,请重新恢复以下数据

<code>models.Group.objects.create(name</code><code>=</code><code>'市场部'</code><code>)</code>

<code>models.Group.objects.create(name</code><code>=</code><code>'技术部'</code><code>)</code>

<code>models.Group.objects.create(name</code><code>=</code><code>'财务部'</code><code>)</code>

<code>models.Group.objects.create(name</code><code>=</code><code>'运维部'</code><code>)</code>

<code>models.Group.objects.create(name</code><code>=</code><code>'销售部'</code><code>)</code>

set()

<code>如果传入过来的数据在表中没有,那么就添加进来,如果有那么就进行移除</code>

<code>接收一个参数clear,如果clear</code><code>=</code><code>true,那么就先全部清除,然后再添加,默认clear</code><code>=</code><code>false</code>

<code>&gt;&gt;&gt; host.group_set.</code><code>set</code><code>(models.Group.objects.</code><code>filter</code><code>(gid</code><code>=</code><code>6</code><code>))</code>

create()

<code># gid大于8的全部加入进来,相当于add()</code>

<code>&gt;&gt;&gt; host.group_set.add(</code><code>*</code><code>models.Group.objects.</code><code>filter</code><code>(gid__gt</code><code>=</code><code>8</code><code>))</code>

get_or_create()

<code># 如果有就获取,没有就添加,元数据也会被添加</code>

<code>&gt;&gt;&gt; host </code><code>=</code><code>models.Host.objects.get(ip</code><code>=</code><code>'192.168.1.3'</code><code>)</code>

<code>&gt;&gt;&gt; r </code><code>=</code> <code>host.group_set.get_or_create(name</code><code>=</code><code>'技术部'</code><code>)</code>

<code># 如果没有,返回True,并添加数据</code>

<code>&gt;&gt;&gt; r</code>

<code>(&lt;Group: Group </code><code>object</code><code>&gt;, </code><code>True</code><code>)</code>

<code># 已经有了,返回False,不执行任何操作</code>

<code>(&lt;Group: Group </code><code>object</code><code>&gt;, </code><code>False</code><code>)</code>

update_or_create()

与上述方法一致

自定义的第三张表不会创建联合唯一索引,Unique

在对第三张表操作的时候,只能使用第三张表明进行操作

第三张表添加约束

<code># 在第三张表内添加下面的类</code>

<code>class</code> <code>Meta:</code>

<code>    </code><code>unique_together </code><code>=</code> <code>[</code>

<code>        </code><code>(</code><code>'host_id'</code><code>, </code><code>'group_id'</code><code>)</code>

<code>    </code><code>]</code>

插入一条数据

<code># 两个外键都会加上_id</code>

<code>&gt;&gt;&gt; models.HostGroup.objects.create(host_id_id</code><code>=</code><code>1</code><code>, group_id_id</code><code>=</code><code>1</code><code>)</code>

<code>&lt;HostGroup: HostGroup </code><code>object</code><code>&gt;</code>

本文转自 Edenwy  51CTO博客,原文链接:http://blog.51cto.com/edeny/1925052,如需转载请自行联系原作者