다에서 다로 필드를 직렬화하는 장고레스트 프레임워크
다대다 필드를 목록으로 직렬화하고 휴식 프레임워크를 통해 반환하려면 어떻게 해야 합니까?아래의 예에서, 저는 게시물과 관련된 태그 목록을 함께 반환하려고 합니다.
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
당신은 필요할 것입니다.TagSerializer
,누구의.class Meta
가지다model = Tag
.끝나고TagSerializer
생성, 수정PostSerializer
와 함께many=True
당분간ManyToManyField
관계:
class PostSerializer(serializers.ModelSerializer):
tag = TagSerializer(read_only=True, many=True)
class Meta:
model = Post
fields = ('tag', 'text',)
이것이 제가 한 일입니다. 한 책에 두 명 이상의 저자가 있을 수 있고 한 작가가 두 권 이상의 책을 가질 수 있다고 가정해 보겠습니다.모델 상:
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)
직렬화기:
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')
@Brian의 답 "tags"에 [{"name": "tag1"}]를 추가하면 다음과 같이 "tags": ["tag1", "tag2", ...]로 단순화할 수 있습니다.
class TagListingField(serializers.RelatedField):
def to_representation(self, value):
return value.name
class PostSerializer(serializers.ModelSerializer):
tag = TagListingField(many=True, read_only=True)
class Meta:
...
자세한 내용은 여기: https://www.django-rest-framework.org/api-guide/relations/ #custom-relational-fields
기본값ModelSerializer
관계에 기본 키를 사용합니다.그러나 다음을 사용하여 내포된 표현을 쉽게 생성할 수 있습니다.Meta
depth
속성:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ("text", "tag")
depth = 1
설명서에 언급된 대로:
그
depth
플랫 표현으로 되돌리기 전에 통과해야 하는 관계의 깊이를 나타내는 정수 값으로 옵션을 설정해야 합니다.
이것은 나에게 효과가 있습니다.
tag = TagSerializer(source="tag", read_only=True, many=True)
장고 2.0
다수에서 다수의 필드에 대해 특정 필드를 원하는 경우:
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',)
init의 serializer 메서드에서 쿼리 세트를 필드로 전달하고 rest_framework에서 해당 쿼리 세트의 ids를 검증할 수 있습니다.
먼저 직렬화기에서 직렬화기를 확장합니다.모델 직렬화 장치
class YourSerializer(serializers.ModelSerializer):
메타 클래스에 필드 포함
class YourSerializer(serializers.ModelSerializer):
class Meta:
fields = (..., 'your_field',)
init 방법:
def __init__(self, *args, **kwargs):
super(YourSerializer, self).__init__(*args, **kwargs)
self.fields['your_field].queryset = <the queryset of your field>
일반적으로 하는 것처럼 필터 또는 제외를 사용하여 인수에서 해당 필드에 대한 쿼리 집합을 제한할 수 있습니다.모두 포함시키고 싶은 경우 그냥 use .objects.all()
models.py
class Tag(models.Model):
name = models.CharField(max_length=100)
# ===============
# ... rest of the fields ...
class Post(models.Model):
tag = models.ManyToManyField(Tag)
text = models.CharField(max_length=100)
serialiazers.py
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = '__all__'
class PostSerializer(serializers.ModelSerializer):
tags = TagSerializer(many=True, read_only=True)
class Meta:
model = Post
fields = ("text", "tag")
views.py
## FUNCTION BASED VIEW
def fbvPost_ListView(request):
# list
if request.method == "GET":
posts = Post.objects.all()
serializer = PostSerializer(instance=posts, many=True)
return JsonResponse(serializer.data, safe=False)
return JsonResponse({"success": False})
# ===========================================================
## CLASS BASED VIEW
class cbvPost_ListView(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
NB: 태그, 포스트는 두 가지 모델이며 우리는 그것들을 연재해야 합니다.여기서 포스트 모델은 태그 모델의 종속성을 가지므로 여기서는 [tag=TagSerializer(many=True, read_only=True)] 또는 이를 반환하는 기본 필드 값을 명시적으로 언급합니다.
안녕하세요. 업데이트 및 생성을 위해 많은 분들께 보여드리겠습니다.그 행사는 많은 춤을 출 수 있고 춤은 많은 행사를 할 수 있다는 맥락입니다.
요청 사항은 다음과 같습니다.
{
"competition": 2,
"title": "the title",
"dances":[ {"id":1},{"id":2}],
"description": "the desc"
}
The Create Function will be as followed.
def create(self, validated_data):
try:
dance_ids = []
for dance in self.initial_data['dances']:
if 'id' not in dance:
raise serializers.ValidationError({'detail': 'key error'})
dance_ids.append(dance['id'])
new_event = models.Event.objects.create(**validated_data)
if dance_ids:
for dance_id in dance_ids:
new_event.dances.add(dance_id)
new_event.save()
return new_event
except Exception as e:
raise serializers.ValidationError({'detail': e})
The Update Function will be as followed.
def update(self, instance, validated_data):
# Delete all records of genres.
try:
for current_genre in instance.dances.all():
instance.dances.remove(current_genre)
# Repopulate genres into instance.
for dance in self.initial_data['dances']:
if 'id' not in dance:
raise serializers.ValidationError({'detail': 'key error'})
dance_obj = models.Dance.objects.get(pk=dance['id'])
instance.dances.add(dance_obj)
event_updated = super().update(instance, validated_data)
return event_updated
except Exception as e:
raise serializers.ValidationError({'detail': e})
만약 당신이 단지 "춤"을 추고 싶다면:[1,2] 대신에, 단지 몇 가지 수정을 하세요.
for dance in self.initial_data['dances']:
if 'id' not in dance:
raise serializers.ValidationError({'detail': 'key error'})
dance_ids.append(dance['id'])
파트. 이것이 여러분에게 도움이 될 수 있기를 바랍니다!
먼저, 태그도 자체 직렬화기가 필요합니다.
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = '__all__'
그런 다음 PostSerializer에서 한 줄을 추가합니다.
class PostSerializer(serializers.ModelSerializer):
tag = TagSerializer(read_only=True, many=True).data
class Meta:
model = Post
fields = ("text", "tag")
이렇게 하면 포스트의 태그 필드가 태그 ID의 배열이 됩니다.".data" 부분을 넣지 않으면 태그의 모든 속성을 넣을 것이며, 대부분의 경우에는 너무 많을 것입니다.
직렬화기를 사용할 수 있습니다.SlugRelatedField() 또는 직렬화자.StringRelatedField(다수=참) 직렬화 도구 관계
당신의 경우:
class PostSerializer(serializers.ModelSerializer):
tag = serializers.StringRelatedField(many=True) # this will return a list
class Meta:
model = Post
fields = ('tag', 'text',)
언급URL : https://stackoverflow.com/questions/33182092/django-rest-framework-serializing-many-to-many-field
'programing' 카테고리의 다른 글
스프링 부트는 @WebServlet을 지원하지 않습니다. (0) | 2023.07.22 |
---|---|
PHP 5.4 - 'closure $this support' (0) | 2023.07.22 |
장고에서 모든 요청 헤더를 가져오려면 어떻게 해야 합니까? (0) | 2023.07.22 |
워드프레스 테마에 Ajax를 추가하는 방법 (0) | 2023.04.03 |
WooCommerce 미니 카트 위젯에서 카트 및 체크아웃 버튼 링크 변경 (0) | 2023.04.03 |