Djongo : Неподдерживаемый поиск для встроенного поля или объединение в поле не разрешено

#django #mongodb #django-models #django-rest-framework #django-filter

Вопрос:

Я создаю приложение django с MongoDB, используя разъем djongo и django-restframework. Я получаю FieldError, когда пытаюсь выполнить фильтрацию полей встроенного документа. Фильтр отлично работает с полями DBRef, но не с полем встроенного документа.

Ошибка, которую я получаю ,

 django.core.exceptions.FieldError: Unsupported lookup 'city' for EmbeddedField or join on the field not permitted.
 

Мои модели и представления проекта,

#models.py

 from djongo import models


class Address(models.Model):
    city = models.CharField(max_length=10)
    pincode = models.CharField(max_length=10)
    coutry = models.CharField(max_length=10)
    objects = models.DjongoManager()

    class Meta :
        abstract = True

    def __str__(self):
        return self.city


class User(models.Model):
    _id = models.ObjectIdField()
    userId = models.CharField(max_length=10)
    address = models.EmbeddedField(
        model_container=Address)
    objects = models.DjongoManager()
    

    # profilePicture = models.ImageField(upload_to='images/')

    def __str__(self):
        return self.userId


class Patient(models.Model):
    _id = models.ObjectIdField()
    patientId = models.CharField(max_length=10)
    user = models.ForeignKey(User, on_delete=models.PROTECT)

 

#views.py

 from django.shortcuts import render
from rest_framework import serializers
from rest_framework import viewsets
from django_filters import rest_framework as filters
from rest_framework.filters import SearchFilter, OrderingFilter
from djongo.models import Q


from .models import User, Patient, Address


class AddressSerializer(serializers.Serializer):
    street = serializers.CharField()
    city = serializers.CharField()
    pincode = serializers.CharField()
    coutry = serializers.CharField()

    class Meta:
        model = Address
        fields = '__all__'


class UserSerializer(serializers.ModelSerializer):
    address = AddressSerializer()
    class Meta:
        model = User
        fields = '__all__'


class PatientSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Patient
        fields = '__all__'
        debth = 2

    def create(self, validated_data):
        # pop out the dict to create post and item, depend on whether you want to create post or not
        user_payload = validated_data.pop('user')
        print(validated_data)
        # create user
        user_obj = User.objects.create(**user_payload)
        user_obj.status = 'ACTIVE'
        if user_obj:
            # create product item
            patient_post = Patient.objects.create(
                user=user_obj, **validated_data)
        return patient_post


class PatientFilter(filters.FilterSet):
    userId = filters.CharFilter(
        field_name='user__userId', lookup_expr='icontains')

    # city = filters.CharFilter(
    #     field_name='user__address__city', lookup_expr='icontains')
    
    #Custom filter
    userLocation = filters.CharFilter(
        method="my_custom_filter", label="User Location")

    class Meta:
        model = Patient
        fields = ['userId','userLocation']

    def my_custom_filter(self, queryset, name, value):
        return Patient.objects.filter(
            user__address__city=value}
        )


class PatientViewSet(viewsets.ModelViewSet):
    serializer_class = PatientSerializer
    queryset = Patient.objects.all()

    filter_backends = (filters.DjangoFilterBackend,
                       SearchFilter, OrderingFilter)
    filterset_class = PatientFilter
    search_fields = ('user__userId')
    ordering = ('user__userId')
 
 [packages]
django = "==3.1.12"
djongo = "1.3.6"
djangorestframework = "3.12.4"
django-filter = "2.4.0"
 

Я хочу использовать встроенные документы и делать фильтры для них в django, не мог бы кто-нибудь помочь мне с этим ?

Спасибо!

Ответ №1:

Вместо

Patient.objects.filter(user__address__city=value})

попробуйте сделать следующее

Patient.objects.filter(user__address={"city": value})