资讯专栏INFORMATION COLUMN

Django基础之八(模型关系)

lewif / 2436人阅读

摘要:默认情况下,这个管理器的名字为,其中是源模型的小写名称。创建一个新的对象,将它保存并放在关联的对象集中。从关联的对象集中删除指定的模型对象。

模型关系 简介

关系数据库的威力体现在表之间的相互关联,Django提供了三种最常见的数据库关系:多对一(many-to-one),多对多(many-to-many),一对一(one-to-one)

多对一关系

多对多关系

一对一关系

多对一

django是使用django.db.models.ForeignKey 定义多对一关系

ForeignKey需要一个位置参数来指定本Model关联的Model,ForeignKey关联的Model是"一", ForeignKey所在的Model是"多"

比如汽车和制造商的例子,一辆汽车只能属于一个制造商,但是一个制造商有多辆汽车,这个关系,用Django的Model来表示,就是

  class Manufacturer(models.Model):
      name = models.CharField(max_length=30)

  class Car(models.Model):
      manufacturer = models.ForeignKey(Manufacturer)
      name = models.CharField(max_length=30)

数据创建

In [1]: from dashboard.models import Manufacturer,Car                                   
In [2]: m1 = Manufacturer()                                                             
In [3]: m1.name = "丰田"                                                                
In [4]: m1.save()                                                                       
In [5]: m2 = Manufacturer()                                                             
In [6]: m2.name = "大众"                                                                
In [7]: m2.save()                                                                       
In [8]: m1                                                                              
Out[8]: 
In [9]: m2                                                                              
Out[9]: 
In [10]: c1 = Car()                                                                     
In [11]: c1.name = "xxx1"                                                               
In [12]: m = Manufacturer.objects.get(pk=1)                                             
In [13]: c1.manufacturer = m                                                            
In [14]: c1.save()                                                                      
In [15]: c2 = Car()                                                                     
In [16]: c2.name = "宝来"                                                               
In [17]: m3 = Manufacturer.objects.get(pk=2)                                            
In [18]: c2.manufacturer = m3                                                           
In [19]: c2.save()   
多对一查询

正向查询( ForeignKey 所在的模型查询关联的模型)

 In [22]: xxx1 = Car.objects.get(name="xxx1")    
In [23]: xxx1                                               
Out[23]: 
In [24]: xxx1.manufacturer                                                                                                                                                       Out[24]: 
In [25]: xxx1.manufacturer.name                                                                                                                                             Out[25]: "宝马"

反向查询( ForeignKey 指向的模型查询ForeignKey 所在的模型)

如果模型有一个ForeignKey,那么该ForeignKey 所指的模型实例可以通过一个管理器返回前一个有ForeignKey的模型的所有实例。默认情况下,这个管理器的名字为foo_set,其中foo 是源模型的小写名称。该管理器返回的查询集可以用上一节提到的方式进行过滤和操作。

In [27]: m1 = Manufacturer.objects.get(pk=1)                                                                                                                         
In [28]: m1.car_set.all()                                                                                                    
Out[28]: , ]>
In [29]: c2 = Car.objects.get(pk=2)                                       
In [30]: c2                                 
Out[30]: 
In [31]: m1.car_set.add(c2)                       
In [32]: m1.save()   返回多个car对象
多对多

要实现多对多,就要使用django.db.models.ManyToManyField类,和ForeignKey一样,它也有一个位置参数,用来指定和它关联的Model
如果不仅仅需要知道两个Model之间是多对多的关系,还需要知道这个关系的更多信息,比如Person和Group是多对多的关系,每个person可以在多个group里,那么group里可以有多个person

多对多示例
 class Group(models.Model):
     #...

  class Person(models.Model):
      groups = models.ManyToManyField(Group)

建议以被关联模型名称的复数形式做为 ManyToManyField 的名字
在哪个模型中设置 ManyToManyField 并不重要,在两个模型中任选一个即可——不要在两个模型中都设置

用户和组操作实例

In [1]: from django.contrib.auth.models import User,Group                               
In [2]: g = Group.objects.create(name="test")                                           
In [3]: User.objects.all()                                                              
Out[3]: 
In [4]: u = User()                                                                      
In [5]: u.username = "wanghui"                                                          
In [6]: u.email = "122@qq.com"                                                          
In [7]: u.password = "123456"                                                           
In [8]: u.save()                                                                        
In [9]: u1 = User.objects.get(pk=1)                                                     
In [10]: g1 = Group.objects.get(pk=1)                                                   
In [11]: u1.groups                    #证明manytomany在User表                                                    
Out[11]: .ManyRelatedManager at 0x7f3dce15ea58>
In [12]: g1.user_set                                                                    
Out[12]: .ManyRelatedManager at 0x7f3dce0ec748>
In [13]: g1.user_set.add(u1)                                                            
In [14]: g1.save()                                                                      
In [15]: u1 = User.objects.get(pk=1)                                                    
In [16]: u1.groups.all()                                                                
Out[16]: ]>
In [17]: g1 = Group.objects.get(pk=1)                                                   
In [18]: g1.user_set.all()                                                              
Out[18]: ]>
处理关联对象的其它方法
add(obj1, obj2, ...) #添加一指定的模型对象到关联的对象集中。
create(**kwargs) #创建一个新的对象,将它保存并放在关联的对象集中。返回新创建的对象。
remove(obj1, obj2, ...) #从关联的对象集中删除指定的模型对象。
clear() #从关联的对象集中删除所有的对象。
一对一
一对一是通过django.db.models.OneToOneField来实现的,被关联的Model会被加上Unique的限制, OneToOneField要一个位置参数,与模型关联的类
当某个对象想扩展自另一个对象时,最常用的方式就是在这个对象的主键上添加一对一关系
接口小练习

需求:

GET:获取所有用户组列表
GET:获取组下的成员列表
GET:获取用户的组列表
POST:将用户添加至指定组
POST:将用户从指定组中踢出

类视图如下:

from django.contrib.auth.models import User,Group
from django.core import serializers
from django.http import Http404,QueryDict

class GroupListView(View):
    def get(self,request,*args,**kwargs):
        queryset = Group.objects.all()
        return HttpResponse(serializers.serialize("json",queryset),content_type="application/json")

class GroupMembersView(View):
    def get_queryset(self):
        groupObj = self.get_group_obj()
        return groupObj.user_set.all()

    def get_group_obj(self):
        try:
            groupObj = Group.objects.get(name=self.request.GET.get("name"))
        except Group.DoesNotExist:
            return Http404
        except Group.MultipleObjectsReturned:
            return Http404
        return groupObj

    def get(self,request,*args,**kwargs):
        user_queryset = self.get_queryset()
        return HttpResponse(serializers.serialize("json",user_queryset),content_type="application/json")

class UserGroupsView(View):
    def get_queryset(self):
        userObj = self.get_user_obj()
        return userObj.groups.all()

    def get_user_obj(self):
        try:
            userObj = User.objects.get(username=self.request.GET.get("name"))
        except User.DoesNotExist:
            return Http404
        except User.MultipleObjectsReturned:
            return Http404
        return userObj

    def get(self,request,*args,**kwargs):
        group_queryset = self.get_queryset()
        return HttpResponse(serializers.serialize("json",group_queryset),content_type="application/json")

class UserGroupManageView(View):
    def get_query(self):
        groupObj = self.get_group_obj()
        userObj = self.get_user_obj()

    def get_group_obj(self):
        try:
            groupObj = Group.objects.get(name=QueryDict(self.request.body).get("name"))
        except Group.DoesNotExist:
            return Http404
        except Group.MultipleObjectsReturned:
            return Http404
        return groupObj
        return groupObj

    def get_user_obj(self):
        try:
            userObj = User.objects.get(username=QueryDict(self.request.body).get("name"))
        except User.DoesNotExist:
            return Http404
        except User.MultipleObjectsReturned:
            return Http404
        return userObj

    def delete(self,request,*args,**kwargs):
        groupObj = self.get_group_obj()
        userObj = self.get_user_obj()
        groupObj.user_set.remove(userObj)
        return HttpResponse()

    def put(self,request,*args,**kwargs):
        groupObj = self.get_group_obj()
        userObj = self.get_user_obj()
        groupObj.user_set.add(userObj)
        return HttpResponse()

路由:

urlpatterns = [
    url(r"^grouplist/$",views.GroupListView.as_view()),
    url(r"^groupmembers/$",views.GroupMembersView.as_view()),
    url(r"^usergroups/$",views.UserGroupsView.as_view()),
    url(r"^usergroupmanage/$",views.UserGroupManageView.as_view()),
]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/45014.html

相关文章

  • Django Model View Template 之间的简单交互 (二)

    摘要:当然还有其他高级的使用,日后再说完整的用户名邮箱联系地址留言信息用户留言信息使用之前已经定义好了数据模型的字段元数据方法等。 前言 接续前文,上一篇文章主要涉及了 Django 项目的基础配置等,这篇主要涉及数据库相关的 ORM ,也就是 Django 中的 Model 的使用,MVT 三层之间的交互 教程基本都是东拼西凑的,防止有些东西表述不准确,因为我之前写 JavaScript ...

    Coding01 评论0 收藏0
  • django官方文档1.11编翻:首页

    摘要:源网页说明文档所有关于你应该且必须知道的。性能和优化概述的兼容性旨在兼容多种不同版本的支持的兼容性地理框架打算成为世界级的地理框架。其目标是尽可能简单地构建应用程序并利用空间使能数据的功能。 源网页:https://docs.djangoproject.co... django说明文档 所有关于django你应该且必须知道的。 第一步 你是否django编程新手,那就从此开始!从零开始...

    Michael_Lin 评论0 收藏0

发表评论

0条评论

lewif

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<