【问题标题】:Pulling and showing data from associate table in Django rest framework从 Django rest 框架中的关联表中提取和显示数据
【发布时间】:2017-01-16 23:40:15
【问题描述】:

我正在尝试使用 Django Rest Framework 构建 API。我不熟悉。我想知道如何使用引用和关联表提取数据。我有三个模型用户、公司和评论。我将 Auth_token 存储在用户表中,我希望能够通过将身份验证令牌放在地址栏中来提取某个用户的评论。

我的模型是

class User(models.Model):
    user_name = models.CharField(max_length=45)
    email = models.CharField(max_length=255)
    auth_Token = models.CharField(max_length=100,default=uuid.uuid4)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

def __str__(self):
    return self.user_name

class Company(models.Model):
    company_name = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

def __str__(self):
    return self.company_name

class Review(models.Model):
    title = models.CharField(max_length=64)
    rating = models.IntegerField(blank=False)
    summary = models.TextField(max_length=10000)
    ip = models.GenericIPAddressField()
    company = models.ForeignKey(Company)
    user = models.ForeignKey(User)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

def __str__(self):
    return self.title

我目前可以使用以下 apiview 提取评论:

class ReviewView(APIView):
    def get(self,request):
        reviews = Review.objects.all()
        serializer = ReviewSerializer(reviews, many=True)
        return Response(serializer.data)

以及以下序列化器:

 class ReviewSerializer(serializers.ModelSerializer):
     class Meta:
         model = Review
         fields = ('title','company', 'rating', 'summary','user')

请忽略缩进。然而,这导致我只取回公司 ID 和用户 ID。我在这里基本上想知道两件事。

首先我如何提取作为 url 传递的身份验证令牌的数据

url(r'^reviews/(?P<auth_Token>[\w-]+)/$', ReviewView.as_view()),

其次,我如何显示公司名称和用户名而不是 ID。任何帮助都会很棒。谢谢

【问题讨论】:

  • 请注意,Django 的主要优势之一是它的用户模型和用户会话,因此除非您真的知道自己在做什么,否则您不应该创建自己的用户模型。并且 django-rest-framework 支持身份验证令牌,因此您不应该重新发明轮子

标签: django django-rest-framework


【解决方案1】:
  1. 如何根据用户的身份验证令牌过滤评论?

我建议使用ReadOnlyModelViewSet。它将大大减少您的视图代码并允许轻松过滤。处理请求、验证等的大部分平凡而乏味的代码已经写在这些视图集中,因此,您可以只关注业务逻辑而不是服务器端细节。

我没有在 URL 参数本身中使用 auth_Token(例如 reviews/XXX/),而是将其作为查询参数(例如 reviews/?auth_Token=XXX)。这背后的原因是因为 URL 参数本身应该返回一个特定的评论资源,但您需要返回映射到一个用户的过滤评论列表。

 from rest_framework import viewsets

 class ReviewView(viewsets.ReadOnlyModelViewSet):
    serializer_class = ReviewSerializer


    def get_queryset(self):
        """
        This function is called whenever someone tries to retrieve reviews. 
        You do not need to worry about serialization or handling the response 
        as the viewset has set that up with your specified serializer_class
        """

        auth_Token = self.query_params.get("auth_Token", None)
        if auth_Token: # They provided an auth token so we need to filter.
            reviews = Review.objects.filter(user__auth_Token=auth_Token)
        else:
             reviews = Review.objects.all()
        return reviews

在你的urls

url(r'^reviews/$', ReviewView.as_view({"get":"list"})),
  1. 如何在检索到的评论中显示公司名称和用户名而不显示他们的 ID?

您需要使用SlugRelatedField (http://www.django-rest-framework.org/api-guide/relations/#slugrelatedfield)。此字段允许您将典型的id 替换为关联表中的另一个属性。请在下方查看新的ReviewSerializer

class ReviewSerializer(serializers.ModelSerializer):

    company = serializers.SlugRelatedField(read_only=True, slug_field="company_name")

    user = serializers.SlugRelatedField(read_only=True, slug_field="user_name")

    class Meta:
        model = Review
        fields = ('title','company', 'rating', 'summary','user')

【讨论】:

  • 糟糕的是,我可以看到您需要身份验证令牌作为 url 参数。给我一秒钟来修正我的答案。
  • 已修复 - 请查看新答案
  • 如果您只是检索评论列表,请在 urls.py 中尝试 ReviewView.as_view({"get":"list"})。出于某种原因,我的评论之前已作为答案发布。我已经相应地改变了我的答案。
  • 我可能做错了,但这对我不起作用。我得到的第一个错误是:get_queryset() 正好需要 2 个参数(1 个给定) 现在这可能完全错误,但我从 get_queryset(self) 中删除了请求。然后它给了我以下错误:无法将关键字'auth_Token'解析为字段。选项有:company、company_id、created_at、id、ip、rating、summary、title、updated_at、user、user_id
  • 是的,很抱歉,我不小心离开了request。我已经编辑了我的答案。通常来说,reviews/XXXAUTH_TOKEN/ 应该检索一个特定的评论。但是您需要它来检索特定用户的评论。因此,如果您想过滤评论列表,我相信您应该使用查询参数(我最初发布的内容)。我会相应地编辑我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多