根据相关ManyToMany另一个Model id的id过滤查询模型的结果

我有 2 个模型


class Tag(models.Model):

    id = models.AutoField(primary_key=True)

    name = models.CharField(max_length=255)


    def __str__(self):

        return self.name



class Question(models.Model):

    ques_id = models.IntegerField(default=0)

    name = models.CharField(max_length=255)

    Tag_name = models.ManyToManyField(Tag)


    class Meta:

        ordering = ['ques_id']


    def __str__(self):

        return self.name

searlizers.py


class TagSerializers(serializers.ModelSerializer):


    class Meta:

        model = Tag

        fields = '__all__'


class QuestionSerializers(serializers.ModelSerializer):

    class Meta:

        model = Question

        fields = '__all__'

这是我的searilzers课。我想要这样的回应


{

  "id": 1,

  "name": "QUES 1",

  "tags": [{

     "id": 1,

     "name": "Abcd" 

  }]

给定一些输入标签 ID,例如 Tag_id = 1 或 2 或 3,将查询什么来获取 10 个问题。



达令说
浏览 130回答 3
3回答

慕森卡

你只需要tags在你的QuestionSerializersclass QuestionSerializers(serializers.ModelSerializer):    tags = TagSerializers(source='Tag_name', many=True)    class Meta:        model = Question        fields = ('id', 'name', 'tags')它会给你这样的回应{  "id": 1,  "name": "QUES 1",  "tags": [{     "id": 1,     "name": "Abcd"   }]} 您基于标签获取的查询将是这样的Question.objects.filter(Tag_name__in=[1, 2, 4])

千万里不及你

您需要将tags字段作为另一个序列化程序数据添加到您的QuestionSerializer.您的QuestionSerializer代码应如下所示:class QuestionSerializers(serializers.ModelSerializer):    Tag_name = TagSerializer(many=True)    class Meta:        model = Question        fields = '__all__'如果您想要确切tags的名称作为响应,您可以SerializerMethodField这样指定:class QuestionSerializer(serializers.ModelSerializer):    tags = serializers.SerializerMethodField()    get_tags(self, instance):        return TagSerializer(instance.Tag_name, many=True).data    class Meta:        model = Question        fields = ('ques_id', 'name', 'tags')

杨魅力

首先:我建议你重构你的Question模型,因为它有一个ques_id,我认为它被认为是重复的(因为 Django 已经默认创建了一个 id 字段)然后你需要把你ManyToManyField的名字改成tags, makemigrations, 然后migrateclass Question(models.Model):&nbsp; &nbsp; name = models.CharField(max_length=255)&nbsp; &nbsp; tags = models.ManyToManyField(Tag)&nbsp; &nbsp; class Meta:&nbsp; &nbsp; &nbsp; &nbsp; ordering = ['id']&nbsp; &nbsp; def __str__(self):&nbsp; &nbsp; &nbsp; &nbsp; return self.name# run make migrationspython manage.py makemigrations <<<YOUR QUESTIONS APP NAME>>># It will prompt you to check if you change the many to many relationship say yesDid you rename question.Tag_name to question.tags (a ManyToManyField)? [y/N] y# Then Run migratepython manage.py migrate第二:更新您QuestionSerializers以使标签字段序列化关系class QuestionSerializers(serializers.ModelSerializer):&nbsp; &nbsp; tags = TagSerializers(many=True)&nbsp; &nbsp; class Meta:&nbsp; &nbsp; &nbsp; &nbsp; model = Question&nbsp; &nbsp; &nbsp; &nbsp; fields = '__all__'这样你就可以让你的代码更干净。你很高兴。答案更新(过滤和分页)现在,如果您想根据提供的标签 ID 过滤问题。您需要PageNumberPagination用于您的视图,并用于过滤使用DjangoFilterBackend.我建议您将它们设为 DRF 设置的默认值。确保您已django-filter安装。# In your settings.pyREST_FRAMEWORK = {&nbsp; &nbsp; 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',&nbsp; &nbsp; 'DEFAULT_FILTER_BACKENDS': (&nbsp; &nbsp; &nbsp; &nbsp; 'django_filters.rest_framework.DjangoFilterBackend',&nbsp; &nbsp; ),&nbsp; &nbsp; 'PAGE_SIZE': 10}现在创建您的自定义过滤器# Inside filters.pyimport reimport django_filtersfrom questions.models import Questionclass QuestionsFilterSet(django_filters.FilterSet):&nbsp; &nbsp; tags = django_filters.CharFilter(field_name='tags__id', method='tags_ids_in')&nbsp; &nbsp; def tags_ids_in(self, qs, name, value):&nbsp; &nbsp; &nbsp; &nbsp; ids_list = list(map(lambda id: int(id), filter(lambda x: x.isdigit(), re.split(r'\s*,\s*', value))))&nbsp; &nbsp; &nbsp; &nbsp; return qs.filter(**{f"{name}__in": ids_list}).distinct()&nbsp; &nbsp; class Meta:&nbsp; &nbsp; &nbsp; &nbsp; model = Question&nbsp; &nbsp; &nbsp; &nbsp; fields = ('tags',)现在ListAPIView用来列出你的问题class QuestionsListAPIView(ListAPIView):&nbsp; &nbsp; queryset = Question.objects.all()&nbsp; &nbsp; serializer_class = QuestionSerializers&nbsp; &nbsp; filter_class = QuestionsFilterSet现在如果你打http://<PATH_TO_VIEW>?tags=1,2,3您将收到标签 ID 为 1、2 或 3 的所有问题。所有这些问题将一次分页 10 个结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python