使用django Rest框架创建具有外键的模型

时间:2014-09-17 09:56:14

标签: python django api rest django-rest-framework

我有以下型号

class Parent(models.Model):
    address = models.CharField(max_length=30, blank=True, null=True)
    address_no = models.CharField(max_length=4, blank=True, null=True, verbose_name="No")
    phone = models.CharField(max_length=15, blank=True, null=True, verbose_name="Phone Number")
    user = models.OneToOneField(User)

    class Meta:
        verbose_name_plural = "Parents"
        verbose_name = "Parent"

    def __unicode__(self):
        return "%s %s" % (self.user.first_name, self.user.last_name)


class Child(models.Model):
    age = models.IntegerField(blank=True, null=True)
    grade = models.IntegerField(blank=True, null=True)
    user = models.OneToOneField(User)
    parent = models.ForeignKey(Parent, related_name="children")

    class Meta:
        verbose_name = "Child"
        verbose_name_plural = "Children"

    def __unicode__(self): 
        return "%s %s" % (self.user.first_name, self.user.last_name)

所以我的系统上有不同类型的用户(父母和孩子)。我正在使用与User模型的关系来实现它们,因为父项具有与Children不同的字段。 (额外的:有更好的方法吗?)

我还在我的rest api中为这些模型实现了序列化

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = User
        fields = ('id', 'url', 'username', 'email', 'groups')


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name')


class ParentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Parent


class ChildSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Child

并使用视图集生成api和功能的视图

views.py

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_fields = ('username', 'email', 'first_name', 'last_name')


class GroupViewSet(viewsets.ModelViewSet):
    queryset = Group.objects.all()
    serializer_class = GroupSerializer



class ParentViewSet(viewsets.ModelViewSet):
    queryset = Parent.objects.all()
    serializer_class = ParentSerializer


class ChildViewSet(viewsets.ModelViewSet):
    queryset = Child.objects.all()
    serializer_class = ChildSerializer

并设置网址

urls.py

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'parents', views.ParentViewSet)
router.register(r'children', views.ChildViewSet)


urlpatterns = patterns('',
    # Examples:
    url(r'^api/', include(router.urls)),
    url(r'api-auth/', include('rest_framework.urls', namespace='rest_framework')),
)

所以/ api / parents中的帖子会创建一个新的Parent对象。但是它不会创建父模型所必需的用户对象。一种方法是对/ api / users / a post进行2个api调用并创建新用户,然后获取新用户的id并使用它发布到/ api / parents。我想避免这个。在api中创建新父级时有没有办法做到这一点。如何在父列表视图(api / parents /)中返回用户的first_name和last_name。现在它只返回相关用户的url,但没有返回任何字段

1 个答案:

答案 0 :(得分:0)

  

所以我的系统上有不同类型的用户(父母和家人)   儿童)。我正在使用与User模型的关系来实现它们   因为父母与孩子有不同的领域。 (额外的:是吗?   更好的方法吗?)

我宁愿使用逆方法。

Person
   Profile
   Contact
   Graduation

ParentChildRelationship
   Parent (Person)
   Child (Person)

但我想这是一个品味问题。

  

所以/ api / parents中的帖子会创建一个新的Parent对象。但它不会   创建父模型所必需的用户对象。单程   是做2个api调用一个到/ api / users /一个帖子并创建新用户和   然后获取新用户的ID并使用它发布到/ api / parents。我会   喜欢避免这种情况。有没有办法在创建新的时候这样做   来自api的父母。

通过REST,您始终可以根据需要创建新资源。因此,例如,如果您想一次创建资源A和B,那么您可以定义一个名为C的资源,它可以同时创建两个资源。通过阅读也是一样。

在您目前的情况下,您不必定义新资源。用户是父级和子级的嵌入式资源。因此,您必须发送包含该嵌入式资源的表示。通常是普通JSON中的{user: {}}。您可能无法使用当前工具解决这些问题。由于我对django和python一无所知,所以我无能为力。