im filtering that user whoes order_status is completed and who have listing_id 5001. But im getting output data repeated
Here is my Code:
models.py
class Users(models.Model):
name = models.CharField(max_length=100)
phone = models.CharField(max_length=20, blank=True, null=True)
'''
class Meta:
managed = False
db_table = 'users'
class UserOrder2(models.Model):
order_id = models.AutoField(primary_key=True)
order_status = models.CharField(max_length=30,default='None')
listing_id = models.CharField(max_length=250,default='None')
user_id = models.ForeignKey(Users, on_delete=models.CASCADE, db_column="user_id")
'''
class Meta:
managed = False
db_table = 'user_order'
class UserOrderProduct2(models.Model):
order_id = models.ForeignKey(UserOrder2, on_delete=models.CASCADE, db_column="order_id")
product_name = models.CharField(max_length=100)
...
class Meta:
managed = False
db_table = 'user_order_product'
Views.py
class UserPurchaseQuantityView(generics.GenericAPIView):
def post(self, request):
listing_id= request.data.get('listing_id')
kwargs = {}
kwargs['userorder2__listing_id'] = listing_id
kwargs['userorder2__order_status'] = 'Order Delivered'
queryset = Users.objects.filter(**kwargs)
data = UsersSerializer(queryset, many=True).data
return Response(data)
serializers.py
class UserOrderProductSerializer2(serializers.ModelSerializer):
class Meta:
fields = ["product_id", "product_quantity", "product_price", "sub_total",
"product_name"]
model = UserOrderProduct2
class UserOrderSerializer(serializers.ModelSerializer):
product_detail = UserOrderProductSerializer2(source="userorderproduct2_set", many=True)
class Meta:
fields = ["user_id", "order_date", "product_detail"]
model = UserOrder2
class UsersSerializer(serializers.ModelSerializer):
user_detail = UserOrderSerializer(source="userorder2_set", many=True)
class Meta:
fields = "__all__"
model = Users
I'm getting repeated output like this:
[
{
"id": 51238,
"name": "aaa",
"phone": "123456789",
"email": "aaa#gmail.com",
"user_detail": [
{
"user_id": 51238,
"order_date": "2021-07-27 15:55:56"
"product_detail": [
{
"product_id": 20767,
"product_quantity": 1,
"product_price": 150.0,
"sub_total": 150.0,
"product_name": "EMINAZ 2mg Tablet 10's"
]
},
{
"id": 51238,
"name": "aaa",
"phone": "123456789",
"email": "aaa#gmail.com",
"user_detail": [
{
"user_id": 51238,
"order_date": "2021-07-27 15:55:56"
"product_detail": [
{
"product_id": 20767,
"product_quantity": 1,
"product_price": 150.0,
"sub_total": 150.0,
"product_name": "EMINAZ 2mg Tablet 10's"
] },
{
"id": 51238,
"name": "aaa",
"phone": "123456789",
"email": "aaa#gmail.com",
"user_detail": [
{
"user_id": 51238,
"order_date": "2021-07-27 15:55:56"
"product_detail": [
{
"product_id": 20767,
"product_quantity": 1,
"product_price": 150.0,
"sub_total": 150.0,
"product_name": "EMINAZ 2mg Tablet 10's"
] } ]
I think the issue is in **kwargs. Try this
class UserPurchaseQuantityView(generics.GenericAPIView):
def post(self, request):
listing_id= request.data.get('listing_id')
queryset = Users.objects.filter(userorder2__listing_id=listing_id,
userorder2__order_status='Order Delivered')
data = UsersSerializer(queryset, many=True).data
return Response(data)
Add distinct() to make unique.
queryset = Users.objects.filter(**kwargs).distinct()
Related
I have two related models (Product and Recipe). There is a many-to-many relationship defined between them (with a through model). I am able to query the 'through' model fields using the below serializer, but I am unable to make this work the other way around (from Product to Recipe)
models.py:
class Product(models.Model):
version = models.CharField(max_length=4)
displayname = models.CharField(max_length=50,validators=[alphanumeric])
...
class Recipe(models.Model):
...
ingredients = models.ManyToManyField(Product, through='RecipeInput', related_name='recipe_input')
products = models.ManyToManyField(Product, through='RecipeOutput',related_name='recipe_output')
class RecipeInput(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
amount = models.IntegerField(default=1)
amount_min = models.FloatField(blank=True, null=True)
class RecipeOutput(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
amount = models.IntegerField(default=1)
amount_min = models.FloatField(blank=True, null=True)
mj = models.FloatField(blank=True, null=True)
serializers.py:
class RecipeInputSerializer(serializers.HyperlinkedModelSerializer):
product_id = serializers.ReadOnlyField(source='product.id')
product_name = serializers.ReadOnlyField(source='product.displayname')
class Meta:
model = RecipeInput
fields = ('product_id',"product_name", 'amount', 'amount_min', )
class RecipeOutputSerializer(serializers.HyperlinkedModelSerializer):
product_id = serializers.ReadOnlyField(source='product.id')
product_name = serializers.ReadOnlyField(source='product.displayname')
class Meta:
model = RecipeOutput
fields = ('product_id',"product_name", 'amount', 'amount_min', 'mj', )
class ProductInputSerializer(serializers.HyperlinkedModelSerializer):
recipe_id = serializers.ReadOnlyField(source='recipe.id')
recipe_name = serializers.ReadOnlyField(source='recipe.displayname')
class Meta:
model = RecipeInput
fields = ('recipe_id','recipe_name', 'amount_min', 'amount', )
class RecipeSerializer(serializers.ModelSerializer):
ingredients = RecipeInputSerializer(source='recipeinput_set', many=True)
products = RecipeOutputSerializer(source='recipeoutput_set', many=True)
class Meta:
model = Recipe
fields = "__all__"
depth = 1
class ProductSerializer(serializers.ModelSerializer):
products_in = ProductInputSerializer(source='recipe_input', many=True)
class Meta:
model = Product
fields = "__all__"
depth = 1
Now, this works for Recipe, I get the following output:
[
{
"id": 1239,
"ingredients": [
{
"product_id": 1787,
"product_name": "Automated Wiring",
"amount": 15,
"amount_min": 7.5
},
{
"product_id": 1799,
"product_name": "Circuit Board",
"amount": 10,
"amount_min": 5.0
}
],
"products": [
{
"product_name": "Adaptive Control Unit",
"amount": 2,
"amount_min": 1.0,
"mj": 3300.0
}
],
...
},
{
"id": 1240,
"ingredients": [
{
"product_id": 1809,
"product_name": "Copper Sheet",
"amount": 5,
"amount_min": 25.0
},
{
"product_id": 1871,
"product_name": "Quickwire",
"amount": 20,
"amount_min": 100.0
}
],
"products": [
{
"product_name": "AI Limiter",
"amount": 1,
"amount_min": 5.0,
"mj": 180.0
}
],
...
}
]
But, for Product, I am not able to query the related model (Recipe) and the values of the through model. In the serializers.py I defined products_in but it doesnt show recipe_id, recipe_name, etc.
[
{
"id": 2541,
"products_in": [
{
"amount_min": null
}
],
...
},
{
"id": 2542,
"products_in": [
{
"amount_min": null
},
{
"amount_min": null
}
],
...
}
]
I need to get the ItemModel instances from the item model and store them in the foreign key field in the OrderModel but I am not sure how. I've tried to iterate through the item order list and add one but it doesn't display correctly. Any help would be much appreciated.
My goal is to display the data like this:
{
"payment_method": "test",
"confirmation": "14087147WA285750M",
"total_price": "15.00",
"is_paid": "True",
"order_created": "2021-07-09T19:51:18Z",
"item_order": [
{
"id": 2,
"name": "Carrots",
"image": "image link",
"slug": "carrots",
"price": "5.00",
"itemID": "ct1",
"quantity": 1
},
{
"id": 8,
"name": "Dog Food",
"image": "image link",
"slug": "dog-food",
"price": "10.00",
"itemID": "df4",
"quantity": 1
}
]
}
View:
#api_view(['POST'])
def create_order(request):
user = request.user
order = request.data
order_item = OrderModel.objects.create(
user=user,
payment_method=order['payment_method'],
confirmation=order['confirmation'],
total_price=order['total_price'],
is_paid=order['is_paid'],
order_created=order['order_created'],
item_order= """ The item model instance """
)
ordered_items = OrderSerializer(order_item, many=True).data
return Response(ordered_items)
Order Model:
class OrderModel(models.Model):
user = models.ForeignKey(CustomerModel, on_delete=models.CASCADE)
item_order = models.ForeignKey(
ItemModel, on_delete=models.CASCADE)
payment_method = models.CharField(max_length=50)
confirmation = models.CharField(max_length=255)
total_price = models.DecimalField(
max_digits=5, decimal_places=2)
is_paid = models.BooleanField(default=False)
has_been_sent = models.BooleanField(default=False)
order_created = models.DateTimeField()
def __str__(self):
return str(self.id)
Order Serializer:
class OrderSerializer(serializers.ModelSerializer):
item_order = ItemSerializer(many=True)
class Meta:
model = OrderModel
fields = ['payment_method', 'confirmation',
'total_price', 'is_paid', 'has_been_sent', 'order_created',
'item_order']
read_only_fields = ['id']
i have this category models:
class Category(MPTTModel):
name = models.CharField(max_length = 100)
slug = models.SlugField()
parent = TreeForeignKey('self',blank=True, null=True, related_name='children', on_delete=models.CASCADE, db_index = True)
class MPTTMeta:
unique_together = ('slug', 'parent')
verbose_name_plural = "categories"
order_insertion_by = ['name']
def __str__(self):
full_path = [self.name]
k = self.parent
while k is not None:
full_path.append(k.name)
k = k.parent
return ' -> '.join(full_path[::-1])
serializers.py:
category Listing Api
class CategorySerializers(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id','name','slug','children')
def get_fields(self):
fields = super().get_fields()
fields['children'] = CategorySerializer(many=True, read_only=True)
return fields
views.py:
class CategoryView(generics.ListCreateAPIView):
queryset = Category.objects.filter(parent__isnull=True)
serializer_class = CategorySerializers
currently its working but i want to show subcategory inside category only not as a main category as you can see subcategory are listed inside main category and with maincategory also
I am expecting this result:
[
{
"id": 1,
"name": "Animals & Wildlife",
"slug": "animals_wildlife",
"children": []
},
{
"id": 2,
"name": "main cat",
"slug": "mai_cat",
"children": [
{
"id": 3,
"name": "sub_cat",
"slug": "submaincat",
"children": []
}
]
},
{
"id": 4,
"name": "maincat2",
"slug": "maincat2",
"children": [
{
"id": 5,
"name": "submaincat2",
"slug": "submaincat2",
"children": []
}
]
},
{
"id": 6,
"name": "maincat3",
"slug": "maincat3",
"children": []
}
]
...............................................
Change your viewset to
class CategoryViewSet(ModelViewSet):
queryset = Category.objects.filter(parent__isnull=True)
serializer_class = CategorySerializer
and serializer to
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name', 'slug')
def get_fields(self):
fields = super().get_fields()
fields['children'] = CategorySerializer(many=True, read_only=True)
return fields
I'm struggling to write a Django GET that returns the following looking response:
{
"lists": [
{
"id": "123",
"list_order": [
{
"id": "123_1",
"order": 1,
"list_id": "123",
"item_id": 9876,
"item": {
"id": 9876,
"name": "item1",
"location": "California"
}
},
{
"id": "123_2",
"order": 2,
"list_id": "123",
"item_id": 2484,
"item": {
"id": 2484,
"name": "item2",
"location": "California"
}
}
],
"updated_date": "2018-03-15T00:00:00Z"
}
]
}
Given a list_id, the response returns the basic information on the list ("id", "updated_date"), as well as the order of items in the list. Inside each item in the list order, it also grabs the related item details (nested in "item"). I'm able to get this response without the "item" details ("id", "name", "location" fields) and with no error:
{
"lists": [
{
"id": "123",
"list_order": [
{
"id": "123_1",
"order": 1,
"list_id": "123",
"item_id": 9876
},
{
"id": "123_2",
"order": 2,
"list_id": "123",
"item_id": 2484
}
],
"updated_date": "2018-03-15T00:00:00Z"
}
]
}
Again there is no error, and I can retrieve the first nested level without any issue. The problem is getting the "item" information to show within each "list_order". Below are my models, serializers, and views.
models.py
class Lists(models.Model):
id = models.CharField(null=False, primary_key=True, max_length=900)
updated_date = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'tbl_lists'
class Items(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.TextField(blank=True, null=True)
location = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'tbl_items'
class ListOrder(models.Model):
id = models.CharField(null=False, primary_key=True, max_length=900)
list_id = models.ForeignKey(Lists, db_column='list_id', related_name='list_order')
item_id = models.ForeignKey(Items, db_column='item_id', related_name='items')
order = models.BigIntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'tbl_list_order'
serializers.py
class ItemsSerializer(serializers.ModelSerializer):
class Meta:
model = Items
fields = '__all__'
class ListOrderSerializer(serializers.ModelSerializer):
item = ItemsSerializer(many=False, read_only=True)
class Meta:
model = ListOrder
fields = '__all__'
class ListsSerializer(serializers.ModelSerializer):
list_order = ListOrderSerializer(many=True, read_only=True)
class Meta:
model = Lists
fields = '__all__'
views.py
class ListsViewSet(generics.ListCreateAPIView):
"""
API endpoint that returns a list with its meta-information
"""
queryset = Lists.objects.all()
serializer_class = ListsSerializer
def get_queryset(self):
list_id = self.kwargs['list_id']
filters = [Q(id=list_id)]
return Lists.objects.filter(*filters)
def list(self, request, list_id):
queryset = self.get_queryset()
list_serializer = ListsSerializer(queryset, many=True)
return Response({ 'lists': list_serializer.data })
I'm pretty new to Django and like what it offers so far, though maybe I'm thinking of doing this in too much of a "SQL" way. I've read about select_related() and prefetch_related(), but not sure how I would apply it to this case. Any assistance is greatly appreciated and let me know if there's any other information I can provide.
In your ListOrderSerializer you are trying to serialize item. while in ListOrder model you used the field name item_id
Solution:
In ListOrderSerializer:
class ListOrderSerializer(serializers.ModelSerializer):
item_id = ItemsSerializer(many=False, read_only=True)
...
I have the following Django model structure:
class TypeOfIngredient(models.Model):
name = models.CharField(max_length=200,unique=True,null=False)
slug = models.SlugField(unique=True)
class Ingredient(models.Model):
name = models.CharField(max_length=200,unique=True,null=False)
slug = models.SlugField(unique=True)
typeofingredient = models.ForeignKey(TypeOfIngredient, related_name='typeof_ingredient',null=True, blank=True,on_delete=models.PROTECT)
Serializer:
class IngredientListSerializer(ModelSerializer):
class Meta:
model = Ingredient
fields = '__all__'
With the above serializer i see the following api output:
"results": [
{
"id": 1,
"name": "adrak",
"slug": "adrak",
"typeofingredient": null
},
{
"id": 2,
"name": "banana",
"slug": "banana",
"typeofingredient": 1
},
How to get "typeofingredient": "fruit" where fruit is the name field of the typeofingredient. What i am getting is the id.
I tried nested:
class IngredientListSerializer(ModelSerializer):
class Meta:
model = Ingredient
fields = '__all__'
depth = 1
Then i get the api output as:
"results": [
{
"id": 1,
"name": "adrak",
"slug": "adrak",
"typeofingredient": null
},
{
"id": 2,
"name": "banana",
"slug": "banana",
"typeofingredient": {
"id": 1,
"name": "fruit",
"slug": "fruit"
}
},
Here is showing all the details of the typeofingredient. Rather than this can i have directly "typeofingredient": "fruit"
Use serializers.ReadOnlyField
class IngredientListSerializer(ModelSerializer):
typeofingredient = serializers.ReadOnlyField(source='typeofingredient.name')
class Meta:
model = Ingredient
fields = '__all__'
You can add str method on models.py
class TypeOfIngredient(models.Model):
name = models.CharField(max_length=200,unique=True,null=False)
slug = models.SlugField(unique=True)
def __str__(self):
return str(self.name)
class Ingredient(models.Model):
name = models.CharField(max_length=200,unique=True,null=False)
slug = models.SlugField(unique=True)
typeofingredient = models.ForeignKey(TypeOfIngredient, related_name='typeof_ingredient',null=True, blank=True,on_delete=models.PROTECT)