from django.db import models
# django user
from django.contrib.auth.models import User
class Entity(models.Model):
"""
Entity of EAV
"""
entity = models.CharField(max_length=216,
null=False, default='entity_name',
name='entity', verbose_name='Entity of EAV',
db_index=True,
unique=True
)
class Asset(models.Model):
"""
Asset of EAV
"""
asset = models.CharField(max_length=216, null=False,
default='asset', name='asset',
verbose_name='Asset of EAV'
)
entity = models.ForeignKey(to=Entity)
class Meta:
unique_together = ("asset", "entity")
class Value(models.Model):
"""
Value of EAV
"""
value = models.CharField(max_length=216,
null=False, default='value',
name='value', verbose_name='Value of EAV'
)
asset = models.ForeignKey(to=Asset)
owner = models.ForeignKey(User, verbose_name='EAV Owner', related_name='eav')
class Meta:
unique_together = ('value', 'asset', 'owner')
串行器
class EntitySerializer(serializers.Serializer):
id = serializers.IntegerField(label='ID', read_only=True)
entity = serializers.CharField(label='Entity of EAV', max_length=216, required=False)
class AssetSerializer(serializers.Serializer):
id = serializers.IntegerField(label='ID', read_only=True)
asset = serializers.CharField(default='asset', label='Asset of EAV', max_length=216)
entity = EntitySerializer(read_only=True)
class ValueSerializer(serializers.Serializer):
id = serializers.IntegerField(label='ID', read_only=True)
value = serializers.CharField(default='value', label='Value of EAV', max_length=216)
asset = AssetSerializer(read_only=True)
owner = UserModelSerializer(read_only=True)
class EntityAssetValueSerializer(serializers.Serializer):
entity = EntitySerializer(many=True)
asset = AssetSerializer(many=True)
value = ValueSerializer(many=True)
预期序列化
{
"entities": [
{
"entity": "Hero",
"id": 1,
"owner": {
"name": "BatMan",
"id": "1"
},
"groups": [
{
"id": "1",
"name": "SuperHeroes Group"
}
],
"asset": [
{
"asset": "Name",
"value": "BatMan",
"asset_id": 1,
"value_id": 1
},
{
"asset": "Age",
"value": "30",
"asset_id": 1,
"value_id": 2
}
]
},
{
"entity": "Hero",
"id": 1,
"owner": {
"name": "SuperMan",
"id": "2"
},
"groups": [
{
"id": "1",
"name": "SuperHeroes Group"
}
],
"asset": [
{
"asset": "Name",
"value": "SuperMan",
"asset_id": 1,
"value_id": 3
},
{
"asset": "Age",
"value": "30",
"asset_id": 1,
"value_id": 4
}
]
},
{
"entity": "Villian",
"id": 1,
"owner": {
"name": "Joker",
"id": "3"
},
"groups": [
{
"id": "2",
"name": "SuperVillians Group"
}
],
"asset": [
{
"asset": "Name",
"value": "Joker",
"asset_id": 3,
"value_id": 4
},
{
"asset": "Age",
"value": "30",
"asset_id": 4,
"value_id": 5
}
]
},
{
"entity": "Person",
"id": 1,
"owner": {
"name": "Puny Human",
"id": "3"
},
"groups": [
{
"id": "2",
"name": "Humans Group"
}
],
"asset": [
{
"asset": "Name",
"value": "Human Being",
"asset_id": 5,
"value_id": 6
},
{
"asset": "Age",
"value": "30",
"asset_id": 6,
"value_id": 7
}
]
}
]
}
已实现序列化
{
"eav": [
{
"id": 1,
"value": "Human",
"asset": {
"id": 1,
"asset": "Name",
"entity": {
"id": 1,
"entity": "Human"
}
},
"owner": {
"id": 1,
"username": "PunyHuman"
}
},
{
"id": 2,
"value": "26",
"asset": {
"id": 2,
"asset": "Age",
"entity": {
"id": 1,
"entity": "Human"
}
},
"owner": {
"id": 1,
"username": "PunyHuman"
}
},
{
"id": 3,
"value": "26",
"asset": {
"id": 3,
"asset": "Age",
"entity": {
"id": 2,
"entity": "Hero"
}
},
"owner": {
"id": 2,
"username": "BatMan"
}
},
{
"id": 4,
"value": "BatMan",
"asset": {
"id": 3,
"asset": "Name",
"entity": {
"id": 2,
"entity": "Hero"
}
},
"owner": {
"id": 2,
"username": "BatMan"
}
},
{
"id": 5,
"value": "26",
"asset": {
"id": 3,
"asset": "Age",
"entity": {
"id": 2,
"entity": "Hero"
}
},
"owner": {
"id": 3,
"username": "SuperMan"
}
},
{
"id": 6,
"value": "SuperMan",
"asset": {
"id": 4,
"asset": "Name",
"entity": {
"id": 2,
"entity": "Hero"
}
},
"owner": {
"id": 3,
"username": "SuperMan"
}
}
]
}
API查看
class EntityAssetValueAPIView(APIView):
queryset = Value.objects.select_related('asset', 'asset__entity', 'owner')
serializer_class = ValueSerializer
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
lookup_field = 'pk'
# lookup_url_kwarg = None
# The filter backend classes to use for queryset filtering
# filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
# The style to use for queryset pagination.
# pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
# def allowed_methods(self):
# http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
# return http_method_names
def get(self, request, *args, **kwargs):
eav = self.queryset.all()
serializer = self.serializer_class(eav, many=True)
return Response(serializer.data)
我想要做的是,获取分配给用户的所有ENTITIES(以及ASSET和VALUES)。
向用户发布新的实体分配相同的数据。
从我对DRF的理解,我需要一个API视图,API视图会调用序列化程序,所以,我必须创建一个自定义的Serializer,然后保存我必须覆盖create
方法的数据,我将在哪里使用这些单独的序列化程序来验证数据并保存它。
我无法发送所需的RESPONSE或摄取请求。
前进的方向应该是什么?
答案 0 :(得分:1)
我遇到过类似的问题所以我在这里解释一下这个小场景。所以你可以参考一下。
在模型中添加了一些相关名称:
class Asset(models.Model):
"""
Asset of EAV
"""
asset = models.CharField(max_length=216, null=False,
default='asset', name='asset',
verbose_name='Asset of EAV'
)
entity = models.ForeignKey(to=Entity, related_name='asset_entity')
class Value(models.Model):
"""
Value of EAV
"""
value = models.CharField(max_length=216,
null=False, default='value',
name='value', verbose_name='Value of EAV'
)
asset = models.ForeignKey(to=Asset, related_name='asset_value')
owner = models.ForeignKey(User, verbose_name='EAV Owner', related_name='eav')
初始查询集看起来像这样,想法是获取最初需要的所有信息:
queryset = Entity.objects.filter('**condition comes here**')
.values('id', 'entity', 'asset_entity', 'asset_entity__asset', 'asset_entity__asset_value', 'asset_entity__asset_value__value',
'asset_entity__asset_value__owner_id',)
尝试回复时传递此查询集:
serializer = serializer(queryset, many=True, context={'request': request})
Serailizers:
class Owner_Serializer(serializers.ModelSerializer)
class Meta:
model = User
exclude = ('**exclude fields you want to exclude**', )
class EntitySerializer(serializers.Serializer):
id = serializers.IntegerField(source='id')
entity = serializers.CharField(source='entity')
owner = serializers.SerializerMethodField()
groups = serializers.SerializerMethodField()
asset = serializers.SerializerMethodField()
def get_owner(self, obj):
return Owner_Serializer(obj.get('asset_entity__asset_value__owner_id'), context=self.context).data
同样的过程适用于组和资产字段。
在get_owner()
我们有entity object
,我们可以从该对象获得owner_id
,因为我们最初已经获取了相关数据。
所以这里的主要思想是先获取所有数据,然后根据您的要求对这些数据进行序列化。
现有的嵌套Serailization不支持您需要的响应格式。
注意:初始querset非常重要,您可能需要使用相关的预取,因为我们使用反向关系获取数据。此外,我没有测试查询集,因此必须确保使用正确的related_names来获取相关数据。