"[EPIC] Report option on everything - reports models

This commit is contained in:
Eliot Berriot 2019-08-22 11:30:30 +02:00
parent 079671ef7a
commit a6cf2ce019
22 changed files with 792 additions and 21 deletions

View file

@ -1,7 +1,10 @@
import django_filters
from django import forms
from django.core.serializers.json import DjangoJSONEncoder
from django.db import models
from rest_framework import serializers
from . import search
PRIVACY_LEVEL_CHOICES = [
@ -52,3 +55,58 @@ class SmartSearchFilter(django_filters.CharFilter):
except (forms.ValidationError):
return qs.none()
return search.apply(qs, cleaned)
class GenericRelation(serializers.JSONField):
def __init__(self, choices, *args, **kwargs):
self.choices = choices
self.encoder = kwargs.setdefault("encoder", DjangoJSONEncoder)
super().__init__(*args, **kwargs)
def to_representation(self, value):
if not value:
return
type = None
id = None
for key, choice in self.choices.items():
if isinstance(value, choice["queryset"].model):
type = key
id = getattr(value, choice.get("id_attr", "id"))
break
if type:
return {"type": type, "id": id}
def to_internal_value(self, v):
v = super().to_internal_value(v)
if not v or not isinstance(v, dict):
raise serializers.ValidationError("Invalid data")
try:
type = v["type"]
field = serializers.ChoiceField(choices=list(self.choices.keys()))
type = field.to_internal_value(type)
except (TypeError, KeyError, serializers.ValidationError):
raise serializers.ValidationError("Invalid type")
conf = self.choices[type]
id_attr = conf.get("id_attr", "id")
id_field = conf.get("id_field", serializers.IntegerField(min_value=1))
queryset = conf["queryset"]
try:
id_value = v[id_attr]
id_value = id_field.to_internal_value(id_value)
except (TypeError, KeyError, serializers.ValidationError):
raise serializers.ValidationError("Invalid {}".format(id_attr))
query_getter = conf.get(
"get_query", lambda attr, value: models.Q(**{attr: value})
)
query = query_getter(id_attr, id_value)
try:
obj = queryset.get(query)
except queryset.model.DoesNotExist:
raise serializers.ValidationError("Object not found")
return obj