【问题标题】:Django getting ForeignKey objects in APIViewDjango 在 APIView 中获取 ForeignKey 对象
【发布时间】:2018-09-16 23:46:33
【问题描述】:

嘿,我是 Django 新手,我正在使用以下模型编写 REST API。

# models.py
class Order(models.Model):
    order_name = models.CharField(max_length=10, unique=True, default="")

    def __str__(self):
        return '{0}'.format(self.order_name).


class LineItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)

    class Meta:
        unique_together = ('order', 'product')

    def __str__(self):
        return '{} - {}'.format(self.order.order_name, self.product.product_name).


# views.py
class OrderList(APIView):
    def get(self, request):
        orderlist = Order.objects.all()
        serializer = OrderSerializer(orderlist, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = OrderSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class OrderDetail(APIView):
    def get_object(self, order):
        try:
            return Order.objects.get(order_name=order_name)
        except Order.DoesNotExist:
            raise Http404

    def get(self, request, order_name):
        snippet = Order.objects.get(order_name=order_name)
        snippet = snippet.lineitem_set.all()
        serializer = OrderSerializer(snippet)
        return Response(serializer.data)

所以我正在尝试对 OrderDetail(APIView) 的 get 方法进行编码,以便在 /api/order/OrderA/ 我得到 JSON 以及该顺序中的所有 lineitems。我现在已经为此苦苦挣扎了一段时间。有什么建议吗?

class OrderSerializer(serializers.ModelSerializer): class Meta: model = Order fields = ['order_name']

【问题讨论】:

  • 你能在问题中添加 OrderSerializer 类吗?
  • 完成。这就是我所拥有的

标签: django python-3.x django-models django-rest-framework django-views


【解决方案1】:

如下更改您的序列化程序,

class LineItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = LineItem
        fields = ('id', 'product')
        depth = 1


class OrderSerializer(serializers.ModelSerializer):
    line_items = LineItemSerializer(many=True, source='lineitem_set')

    class Meta:
        model = Order
        fields = ['order_name', 'line_items']

然后在您的 OrderDetail 视图中作为

class OrderDetail(APIView):
    # your code

    def get(self, request, order_name):
        snippet = Order.objects.get(order_name=order_name)
        serializer = OrderSerializer(snippet)
        return Response(serializer.data)

【讨论】:

  • 这确实有效。非常感谢。但我还有一个问题。是否可以取回字段名而不是字段 ID?这将使模型变得更好。获取 product_name 作为响应也很重要
  • @NavrajSinghChhina 在LineItemSerializer 中添加depth=1。更新了答案
  • @NavrajSinghChhina 如果解决了问题,您应该标记答案
【解决方案2】:

DRF 为您提供了一个类来获取对象的详细信息。看看这里:http://www.django-rest-framework.org/api-guide/generic-views/#retrieveapiview

如果 order_name 使用 GET 方法作为参数在 url 中传递,这个示例代码应该可以工作。

from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator
from rest_framework.exceptions import NotFound
from rest_framework.generics import RetrieveAPIView

# the decorator avoid to cache the object, maybe you don't need that.
@method_decorator(never_cache, name="dispatch")
class OrderDetail(RetrieveAPIView):

    serializer_class = OrderSerializer

    def get_object(self):
        try:
            return Order.objects.get(order_name=self.kwargs.get('order_name'))
        except Order.DoesNotExist:
            raise NotFound()

【讨论】:

  • 我想你没有得到我的问题,这个东西只是返回 Order_name 而已。我需要使用 order_name=order_name 获取 LineItem 中的所有字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 2017-08-06
  • 2015-10-08
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多