Reputation: 1751
I have the model structure like below
class BaseProduct:
id = models.CharField(max_length=15)
name = models.CharField(max_length=20)
class Product
base_product = ForeigKey(BaseProduct)
name = models.CharField(max_length=20)
class Condition:
category = models.ForeignKey(Product, related_name='allowed_product')
check = models.IntegerField(default=0)
allow = models.PositiveSmallIntegerField(default=1)
The query:
Product.objects.filter(condition__allow=1, condition__check=1)
I want format something like below Base Product and inside that list of products based on allow and check filter
[
{
"name": "BaseProduct 1",
"products": [
{
"name": "TV",
}, {}, ....
]
},
........
]
Upvotes: 0
Views: 1208
Reputation:
Try it, if you use django rest framework
from rest_framework import serializers
from rest_framework.fields import empty
from django.utils.functional import cached_property
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('name')
class BaseProductSerializer(serializers.ModelSerializer):
products = serializers.SerializerMethodField()
class Meta:
model = BaseProduct
fields = ('name', 'products')
def __init__(self, instance=None, data=empty, **kwargs):
self._condition_allow = kwargs.pop('condition_allow', 1)
super(BaseProductSerializer, self).__init__(instance=None, data=empty, **kwargs)
@cached_property
def _request_data(self):
request = self.context.get('request')
# if POST
# return request.data if request else {}
# if GET params
return request.query_params if request else {}
@cached_property
def _condition(self):
return self._request_data.get('CONDITION_PARAM_NAME')
def get_products(self, obj):
qs = obj.product_set.filter(condition__allow=self._condition_allow, condition__check=1)
serializer = ProductSerializer(qs, many=True)
# ^^^^^
return serializer.data
in view
serialiser(qs, condition_allow=5)
Upvotes: 1
Reputation: 5599
Change your models to have related_name
for the foreignkeys to have reverse relationship:
class BaseProduct:
id = models.CharField(max_length=15)
name = models.CharField(max_length=20)
class Product
base_product = ForeigKey(BaseProduct, related_name='products')
name = models.CharField(max_length=20)
class Condition:
category = models.ForeignKey(Product, related_name='conditions')
check = models.IntegerField(default=0)
allow = models.PositiveSmallIntegerField(default=1)
So now you can use it in your serializers:
class BaseProductSerializer:
class Meta:
model = BaseProduct
fields = ('name', 'products',)
class ProductSerializer:
class Meta:
model = Product
fields = ('conditions',)
class ConditionSerializer:
class Meta:
model = Condition
fields = '__all__'
Finally in your views, change this:
Product.objects.filter(condition__allow=1, condition__check=1)
into this:
BaseProduct.objects.filter(products__conditions__allow=1, products__conditions__allow=1)
And hopefully, this should generate JSON data in the format that you asked for.
Upvotes: 1