關係數據庫的威力體如今表之間的相互關聯,Django提供了三種最多見的數據庫關係:多對一(many-to-one),多對多(many-to-many),一對一(one-to-one)數據庫
好比汽車和製造商的例子,一輛汽車只能屬於一個製造商,可是一個製造商有多輛汽車,這個關係,用Django的Model來表示,就是django
class Manufacturer(models.Model): name = models.CharField(max_length=30) class Car(models.Model): manufacturer = models.ForeignKey(Manufacturer) name = models.CharField(max_length=30)
數據建立json
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]: <Manufacturer: Manufacturer object> In [9]: m2 Out[9]: <Manufacturer: Manufacturer object> 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()
In [22]: xxx1 = Car.objects.get(name="xxx1") In [23]: xxx1 Out[23]: <Car: Car object> In [24]: xxx1.manufacturer Out[24]: <Manufacturer: Manufacturer object> In [25]: xxx1.manufacturer.name Out[25]: '寶馬'
若是模型有一個ForeignKey,那麼該ForeignKey 所指的模型實例能夠經過一個管理器返回前一個有ForeignKey的模型的全部實例。默認狀況下,這個管理器的名字爲foo_set,其中foo 是源模型的小寫名稱。該管理器返回的查詢集能夠用上一節提到的方式進行過濾和操做。app
In [27]: m1 = Manufacturer.objects.get(pk=1) In [28]: m1.car_set.all() Out[28]: <QuerySet [<Car: Car object>, <Car: Car object>]> In [29]: c2 = Car.objects.get(pk=2) In [30]: c2 Out[30]: <Car: Car object> In [31]: m1.car_set.add(c2) In [32]: m1.save() 返回多個car對象
要實現多對多,就要使用django.db.models.ManyToManyField類,和ForeignKey同樣,它也有一個位置參數,用來指定和它關聯的Model
若是不單單須要知道兩個Model之間是多對多的關係,還須要知道這個關係的更多信息,好比Person和Group是多對多的關係,每一個person能夠在多個group裏,那麼group裏能夠有多個personui
class Group(models.Model): #... class Person(models.Model): groups = models.ManyToManyField(Group) 建議以被關聯模型名稱的複數形式作爲 ManyToManyField 的名字 在哪一個模型中設置 ManyToManyField 並不重要,在兩個模型中任選一個便可——不要在兩個模型中都設置
用戶和組操做實例url
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]: <QuerySet []> 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]: <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager at 0x7f3dce15ea58> In [12]: g1.user_set Out[12]: <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.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]: <QuerySet [<Group: test>]> In [17]: g1 = Group.objects.get(pk=1) In [18]: g1.user_set.all() Out[18]: <QuerySet [<User: wanghui>]>
add(obj1, obj2, ...) #添加一指定的模型對象到關聯的對象集中。 create(**kwargs) #建立一個新的對象,將它保存並放在關聯的對象集中。返回新建立的對象。 remove(obj1, obj2, ...) #從關聯的對象集中刪除指定的模型對象。 clear() #從關聯的對象集中刪除全部的對象。
一對一是經過django.db.models.OneToOneField來實現的,被關聯的Model會被加上Unique的限制, OneToOneField要一個位置參數,與模型關聯的類 當某個對象想擴展自另外一個對象時,最經常使用的方式就是在這個對象的主鍵上添加一對一關係
需求:3d
GET:獲取全部用戶組列表
GET:獲取組下的成員列表
GET:獲取用戶的組列表
POST:將用戶添加至指定組
POST:將用戶從指定組中踢出
類視圖以下:code
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()), ]