2

We have the SecurityEventItem that have the owner taken from another security_location model and returned.

The logic behind not having security_location direct as a foreign key is that we get events with security_location names that are not added yet to database, but we want them to be registered without adding the missing security location to the database.


class SecurityEventItemGetSerializer(serializers.ModelSerializer):
    epc = RfidTagNestedSerializer()
    owner = serializers.SerializerMethodField('get_owner')
    def get_owner(self, member):
        location = SecurityLocationSerializer(models.SecurityLocation.objects.get(name=member.security_location)).data
        owner_name = ProductOwnerSerializer(models.ProductOwner.objects.get(id=location["owner"])).data
        return owner_name["owner_name"]

    class Meta:
        model = models.SecurityEventItem
        fields = ["id", "epc", "acknowledged", "firstSeenTimestamp", "security_location", "owner"]

The ViewSet bellow

class SecurityEventItemGetViewset(viewsets.ModelViewSet):
    """SecurityEventItemGet Viewset
    API endpoint that allows security event items to be viewed.
    Allowed actions:
        "GET"
    """

    queryset = models.SecurityEventItem.objects.all()
    serializer_class = serializers.SecurityEventItemGetSerializer
    http_method_names = ['get']
    filter_backends = [DjangoFilterBackend]
    search_fields = ["owner"]
    filterset_fields = {
        'acknowledged': ['exact'],
        'epc': ['exact', "in"],
        'security_location': ['exact', "in"],
        'firstSeenTimestamp': ['gte', 'lte'],
    }

I have tryed SearchFilter unsuccesfull as simillar to DjangoFilterBackend it does not recognize the owner field added that does not belong to the SecurityEventItem model.

The response is like this: and I would like to make a filter on the request passing a parameter "owner" added to the existing ones.

[
    {
        "id": 73,
        "epc": {
            "id": 8371,
            "number": "1234",
            "product": {
                "id": 1,
                "name": "default_product",
                "ean": "",
                "description": "default product for foreign/unknown RFID tags",
                "category": {
                    "id": 1,
                    "name": "default_category",
                    "description": "default category for foreign/unknown RFID tags"
                },
                "info": []
            },
            "state": 1,
            "info": [],
            "owner": {
                "id": 1,
                "owner_id": 1,
                "owner_name": "George"
            }
        },
        "acknowledged": false,
        "firstSeenTimestamp": "2022-02-21T09:44:08",
        "security_location": "Test Location",
        "owner": "Second Owner"
    },
    {
        "id": 72,
        "epc": {
            "id": 105177,
            "number": "303625D4580B2484000002CA",
            "product": {
                "id": 590,
                "name": "A78R07",
                "ean": "5940000792305",
                "description": "Fata de perna 50x70",
                "category": {
                    "id": 1,
                    "name": "default_category",
                    "description": "default category for foreign/unknown RFID tags"
                },
                "info": "{\"company\": \"HOTEL Nr1\"}"
            },
            "state": 1,
            "info": [],
            "owner": {
                "id": 1,
                "owner_id": 1,
                "owner_name": "Regina"
            }
        },
        "acknowledged": false,
        "firstSeenTimestamp": "2022-02-21T09:31:16",
        "security_location": "Front Desk",
        "owner": "Second Company"
    }
]

I would really appreciate if someone could teach me how to do that, there are plenty of information regarding model filtering, but no filters for the filters added to extra fields

ElvisM
  • 21
  • 2

1 Answers1

1

SerializerMethodField is read-only. This field is generated only at the time of serialization and does not exist in the database. Filters work only with the database, but the owner field is not there.

I think you should annotate the queryset with the data you want (.annotate(owner=...), Subquery() ), then the filter can work because that field will be returned from the database.

Sergey M
  • 21
  • 1
  • 6