Khung phần còn lại Django tuần tự nhiều lĩnh vực


84

Làm cách nào để sắp xếp thứ tự một trường nhiều đến nhiều thành danh sách một thứ gì đó và trả lại chúng thông qua khung phần còn lại? Trong ví dụ của tôi bên dưới, tôi cố gắng trả lại bài đăng cùng với danh sách các thẻ được liên kết với nó.

models.py

class post(models.Model):
    tag = models.ManyToManyField(Tag)
    text = models.CharField(max_length=100)

serializers.py

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag"??)

views.py

class PostViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

Sử dụng trợ giúp từ @Brian, tôi quản lý để liệt kê các mục trong biểu mẫu này: "tags": [{"name": "tag1"}]. Tôi muốn đơn giản hóa nó vào danh sách, là nó có thể: "thẻ": [ "TAG1", "TAG2", ...]
kengcc

2
sử dụng `tags = serializers.SlugRelatedField (nhiều = True, READ_ONLY = True, slug_field = 'tiêu đề', // fireld thẻ của bạn muốn hiển thị allow_null = True)` trong PostSerializers
M. Dhaouadi

Câu trả lời:


104

Bạn sẽ cần một TagSerializer, mà class Metamodel = Tag. Sau khi TagSerializerđược tạo, hãy sửa đổi PostSerializervới many=Truecho một ManyToManyFieldquan hệ:

class PostSerializer(serializers.ModelSerializer):
    tag = TagSerializer(read_only=True, many=True)

    class Meta:
        model = Post
        fields = ('tag', 'text',)

Câu trả lời dành cho DRF 3


nó hoạt động !!! : D Có ý kiến ​​gì về cách biến bộ tuần tự này thành một danh sách được phân tách bằng dấu phẩy không? lớp TagSerializer (serializers.ModelSerializer): lớp Meta: mô hình = Tag lĩnh vực = ( 'name')
kengcc

1
Ngay bây giờ, tôi nhận được: "tags": [{"name": "tag1"}] Tôi muốn đơn giản hóa nó thành: "tags": ["tag1", "tag2", ...]
kengcc

tags = serializers.ListField (source = 'tag'). Điều này sẽ giúp bạn có được danh sách các str đại diện của từng đối tượng của thẻ
Sachin Gupta

2
Điều gì xảy ra nếu bạn muốn có thể cập nhật thẻ thông qua Bài đăng? (ví dụ: not read_only) Tôi nhận được hành vi kỳ lạ khi xóa read_only và cố gắng XEM bản cập nhật cho trường thẻ (tôi gặp lỗi về thẻ đã tồn tại)
getup

1
Các read_only=Truephần được giải thích ở đây: django-rest-framework.org/api-guide/relations/...
Pavel Vergeev

24

Đây là những gì tôi đã làm, giả sử một Sách có thể có nhiều tác giả và Tác giả có thể có nhiều hơn một cuốn sách: Trên Mô hình:

class Author(models.Model):
    name = models.CharField(max_length=100, default="")
    last_name = models.IntegerField(default=0)

class Book(models.Model):
    authors = models.ManyToManyField(Author, related_name="book_list", blank=True)
    name = models.CharField(max_length=100, default="")
    published = models.BooleanField(default=True)

Trên Serializers:

class BookSerializer(serializers.ModelSerializer):
    authors = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all(), many=True)

    class Meta:
        model = Book
        fields = ('id', 'name', 'published', 'authors')


class AuthorSerializer(serializers.ModelSerializer):
    book_list = BookSerializer(many=True, read_only=True)

    class Meta:
        model = Author
        fields = ('id', 'name', 'last_name', 'book_list')

Bất kỳ ý tưởng nào về cách chúng tôi có thể tạo tác giả trên thực thể Tạo của Sách ??
Kishan Mehta

2
Vâng, nó đã được thực hiện trên lớp xem, xin vui lòng gửi câu hỏi khác nếu bạn muốn có một câu trả lời chi tiết hơn
Chúa Giêsu Almaral - Hackaprende

8

Việc thêm vào câu trả lời của @ Brian "thẻ": [{"name": "tag1"}] có thể được đơn giản hóa thành "thẻ": ["tag1", "tag2", ...] theo cách này:

class PostSerializer(serializers.ModelSerializer):
    tag = TagSerializer(read_only=True, many=True)

    class Meta:
        ...

class TagSerializer(serializers.RelatedField):

     def to_representation(self, value):
         return value.name

     class Meta:
        model = Tag

Thông tin thêm tại đây: https://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields


4

Điều này làm việc cho tôi.

tag = TagSerializer(source="tag", read_only=True, many=True)

4

Django 2.0

Đối với nhiều lĩnh vực, nếu bạn muốn một lĩnh vực cụ thể:

class QuestionSerializer(serializers.ModelSerializer):

    topics_list = serializers.SerializerMethodField()

    def get_topics_list(self, instance):
        names = []
        a = instance.topics.get_queryset()
        for i in a:
            names.append(i.desc)
        return names
    class Meta:
        model = Question
        fields = ('topics_list',)

Đối với get_topics_listbạn có thể đơn giản hóa đếnreturn list(instance.topics.values_list('desc', flat=True))
bdoubleu

2

Trong phương thức serializer trên init, bạn có thể chuyển bộ truy vấn vào trường và rest_framework đánh giá các id trên bộ truy vấn đó

1) trước tiên hãy mở rộng bộ nối tiếp của bạn khỏi bộ nối tiếp.

class YourSerializer(serializers.ModelSerializer):

2) đưa trường vào meta class

class YourSerializer(serializers.ModelSerializer):
  class Meta:
        fields = (..., 'your_field',)

3) trong phương thức init:

def __init__(self, *args, **kwargs):
    super(YourSerializer, self).__init__(*args, **kwargs)
    self.fields['your_field].queryset = <the queryset of your field>

Bạn có thể giới hạn bộ truy vấn cho trường đó trong bất kỳ đối số nào bằng cách sử dụng bộ lọc hoặc loại trừ như bình thường bạn làm. Trong trường hợp bạn muốn bao gồm tất cả, chỉ cần sử dụng .objects.all ()


1

Mặc định ModelSerializersử dụng khóa chính cho các mối quan hệ. Tuy nhiên, bạn có thể dễ dàng tạo các biểu diễn lồng nhau bằng cách sử dụng Meta depththuộc tính:

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag")
        depth = 1 

Như đã đề cập trong tài liệu :

Các depthtùy chọn nên được đặt thành một giá trị số nguyên cho biết chiều sâu của mối quan hệ đó phải được đi qua trước khi quay trở lại một đại diện phẳng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.