ORM 'like' query in django python - python

keywords=Donut working with keyword__name__in=Donut
but i need to get result keyword__name__in=Don
views.py
items=ItemVariation.objects.filter(item__restaurant__id = i['restaurant']['id'],keyword__name__in=keyword,keyword__mood__moods=mood).select_related()
# items=ItemVariation.objects.filter(item__restaurant__id = i['restaurant']['id'],keyword__name__contains=keyword,keyword__mood__moods=mood).select_related() # it is returning null
# items=ItemVariation.objects.filter(item__restaurant__id = i['restaurant']['id'],keyword__name__icontains=keyword,keyword__mood__moods=mood).select_related()
models.py
class Keyword(models.Model):
name=models.CharField(max_length=500,unique=True)
image = models.ImageField(upload_to='keywords/', blank=True, null=True)
mood=models.ManyToManyField(Mood,blank=True)
def __str__(self):
return str(self.name)
class ItemVariation(models.Model):
restaurant=models.ForeignKey(Restaurant,on_delete=models.CASCADE)
item=models.ForeignKey(Item,on_delete=models.CASCADE)
price=models.IntegerField(blank=True,null=True,default=0)
item_code=models.CharField(max_length=500)
keyword= models.ManyToManyField(Keyword)
image=models.ImageField(upload_to='dishes/', blank=True, null=True)
i have this query i need to use keyword__name__in= %keyword% as a like
i'm using PostgreSQL database
parameter that i'm passing for this /?keywords=Donut&mood=Dating
result when i'm using keyword__name__in
"items": [
{
"id": 7,
"item": {
"name": "Donut",
"short_description": "Donuts"
},
"price": 0,
"item_code": "test",
"image": "/media/dishes/download_3_kcE78IS.jpeg",
"restaurant": 1,
"keyword": [
3
]
}
],
result when i'm using icontains
"items": [],

You're looking for contains (or icontains)
keyword__name__contains=keyword

Related

How to GET multipule ModelSrializer in one APIVIEW using Django Rest Framework

I have UserModel each user has multiple package and each package have price and program.
model.py:
class User(models.Model):
name= models.CharField(max_length=100)
class Package(models.Model):
package_name = models.CharField(max_length=100)
user= models.ForeignKey(User, on_delete=models.CASCADE,related_name='user_package')
class Program(models.Model):
title = models.CharField(max_length=100)
user_package = models.ForeignKey(Package, on_delete=models.CASCADE)
class Price(models.Model):
price = models.FloatField()
user_package = models.ForeignKey(Package, on_delete=models.CASCADE)
serializer look like:
class UserSerializer(NestedCreateMixin, NestedUpdateMixin,serializers.ModelSerializer):
program = ProgramSerializer(source='user_program', many=True, read_only=True)
package = PackageSerializer(source='user_package', many=True, read_only=True)
price = PriceSerializer(source='price', many=True, read_only=True)
class Meta:
model = User
fields= ("__all__")
views.py:
class user_apiView(APIView):
def get(self, request):
user= user.objects.all()
serializer = UserSerializer(user, many = True)
return Response(serializer.data)
and that what I get:
{
"id": 1,
"package": [
{
"id": 1,
"package_name": "wfe",
"user": 1
},
{
"id": 2,
"package_name": "wfe",
"user": 1
}
]
}
how can GET this RESULT?
{
"id": 1,
"package": [
{
"id": 1,
"package_name": "wfe",
"user": 1
},
{
"id": 2,
"package_name": "wfe",
"user": 1
}
],
"price": [
{
"id": 1,
"price": "wfe",
"package": 1
},
{
"id": 2,
"price": "wfe",
"package": 2
}
]
"program": [
{
"id": 1,
"title": "wfe",
"package": 1
},
{
"id": 2,
"title": "wfe",
"package": 2
}
]
}
The problem is that your price and program models are not directly related to your user model. If you consider the relations it is like price -> package -> user, so you will have to get those relations in the package serializer instead like this
serializers.py
class ProgramSerializer(serializers.ModelSerializer):
class Meta:
model = Program
fields= ("__all__")
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields= ("__all__")
class PackageSerializer(serializers.ModelSerializer):
program = ProgramSerializer(source='program_set', many=True, read_only=True)
price = PriceSerializer(source='price_set', many=True, read_only=True)
class Meta:
model = Package
fields= ("__all__")
class UserSerializer(serializers.ModelSerializer):
package = PackageSerializer(source='user_package', many=True, read_only=True)
class Meta:
model = User
fields= ("__all__")
Note that this will however not give you the output in the format you mentioned though, the price and program fields will instead be nested under package.
[
{
"id": 1,
"package": [
{
"id": 1,
"program": [
{
"id": 1,
"title": "program1",
"user_package": 1
}
],
"price": [
{
"id": 1,
"price": 1000.0,
"user_package": 1
}
],
"package_name": "package1",
"user": 1
},
{
"id": 2,
"program": [
{
"id": 2,
"title": "program2",
"user_package": 2
}
],
"price": [
{
"id": 2,
"price": 1500.0,
"user_package": 2
}
],
"package_name": "package2",
"user": 1
}
],
"name": "user1"
}
]
If you really want the format in the way you posted you might instead want to take a look at https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

how join 3 table in Django Python

This is my first class
class dot_bay(models.Model):
ma_dot_bay = models.CharField(primary_key=True,max_length=255, default=uuid.uuid4, editable=False)
ten_dot_bay = models.CharField(max_length=255, default="")
ngay_bay = models.DateTimeField()```
This is my second class
class video(models.Model):
ma_video = models.CharField(primary_key=True, max_length=255, default=uuid.uuid4, editable=False)
ma_dot_bay = models.ForeignKey(dot_bay, on_delete=models.CASCADE, related_name='dot_bay_video')
video_path = models.TextField()
detected_path = models.TextField()
ngay_upload = models.TextField()
And my third class
class hinh_anh(models.Model):
ma_hinh_anh = models.CharField(primary_key=True, max_length=255, default=uuid.uuid4, editable=False)
ma_video = models.ForeignKey(video, on_delete=models.CASCADE, related_name='video_hinh_anh')
image_base64 = models.TextField()
I try this in my Serializer in my project to display result of 2 join table dot_bay and video
like that
class DotBayModelSerializer(serializers.ModelSerializer):
class Meta:
model = dot_bay
fields = ("ma_dot_bay", "ten_dot_bay", "ngay_bay", "dot_bay_video")
depth = 1
And get the result like that
[
{
"ma_dot_bay": "db0001",
"ten_dot_bay": "Đợt bay",
"ngay_bay": "2021-05-14T15:30:27Z",
"dot_bay_video": [
{
"ma_video": "vd0001",
"video_path": "1",
"detected_path": "1",
"ngay_upload": "1",
"ma_dot_bay": "db0001"
},
{
"ma_video": "vd0002",
"video_path": "1",
"detected_path": "1",
"ngay_upload": "1",
"ma_dot_bay": "db0001"
}
]
},
{
"ma_dot_bay": "db0002",
"ten_dot_bay": "Đợt bay",
"ngay_bay": "2021-05-14T15:31:07Z",
"dot_bay_video": [
{
"ma_video": "vd0003",
"video_path": "1",
"detected_path": "1",
"ngay_upload": "1",
"ma_dot_bay": "db0002"
},
{
"ma_video": "vd0004",
"video_path": "11",
"detected_path": "1",
"ngay_upload": "1",
"ma_dot_bay": "db0002"
}
]
}
]
that's what I expected
But now I want to join 3 table, display like that,
[
{
"ma_dot_bay": "db0002",
"ten_dot_bay": "Đợt bay",
"ngay_bay": "2021-05-14T15:31:07Z",
"dot_bay_video": [
{
"ma_video": "vd0003",
"video_path": "1",
"detected_path": "1",
"ngay_upload": "1",
"ma_dot_bay": "db0002",
"video_hinh_anh": [
{
"ma_hinh_anh": "....."
},
{
"ma_hinh_anh": "....."
}
]
},
{
"ma_video": "vd0004",
"video_path": "11",
"detected_path": "1",
"ngay_upload": "1",
"ma_dot_bay": "db0002",
"video_hinh_anh": [
{
"ma_hinh_anh": "....."
},
{
"ma_hinh_anh": "....."
}
]
}
]
}
]
I try some method but not working :((((
How can I do that ??
The idea here is to use nested serializers. In our case, we'll use those nested serializers to detail how we want foreign key objects to be rendered/structure.
Try something like that:
class NestedHinhAnhModelSerializer(serializers.ModelSerializer):
class Meta:
model = hinh_anh
# Didnt put the `ma_video` field since we're using this serializer inside a video model
fields = ("ma_hinh_anh ", "image_base_64")
class NestedVideoModelSerializer(serializers.ModelSerializer):
# We override the `video_hinh_anh` field with a custom serializer
video_hinh_anh = NestedHinhAnhModelSerializer(many=True)
class Meta:
model = video
# I didnt put the `ma_dot_bay` fk field since we'll be using this serializer inside the dot_bay model
fields = ("ma_video ", "video_path ", "detected_path ", "ngay_upload", "video_hinh_anh")
class NestedVideoModelSerializer(serializers.ModelSerializer):
# We override the `dot_bay_video` with a custom serializer
dot_bay_video = VideoModelSerializer(many=True)
class Meta:
model = dot_bay
fields = ("ma_dot_bay", "ten_dot_bay", "ngay_bay", "dot_bay_video")

how to create multiple objects with one request DRF

I have the following models
class Product(models.Model):
name = models.CharField(null=True, blank=True, max_length=500)
category = models.CharField(null=True, blank=True, max_length=120)
class SpecificationName(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True, related_name='specifications')
name = models.CharField(max_length=125)
class Attribute(models.Model):
spec_name = models.ForeignKey(SpecificationName, on_delete=models.CASCADE, null=True, related_name='attributes')
index = models.CharField(max_length=200, blank=True, null=True)
value = models.CharField(max_length=250, blank=True, null=True)
after saving objects in Django admin I have an example
{
"name": "Apple Smart Watch",
"category": "IT",
"specifications": [
{
"name": "Test Data",
"attributes": [
{
"index": "test",
"value": "test2"
},
{
"index": "test7",
"value": "test8"
},
{
"index": "test9",
"value": "test10"
}
]
},
{
"name": "Test Data Continued",
"attributes": [
{
"index": "bla",
"value": "bla1"
},
{
"index": "bla 2",
"value": "bla 4"
},
{
"index": "test9",
"value": "test10"
}
]
},
{
"name": "Test Spec",
"attributes": []
}
]
}
I need to save this kind of object with one request but I am failing to do this
my serializer looks like this
class ProductSerializer(serializers.ModelSerializer):
specifications = SpecNameSerializer(many=True)
# attributes = AttributeSerializer(many=True, required=False)
class Meta:
model = Product
fields = ['name', 'category', 'brand', 'price', 'specifications']
def create(self, validated_data):
specs = validated_data.pop('specifications')
instance = Product.objects.create(**validated_data)
for spec in specs:
SpecificationName.objects.create(product=instance, **spec)
print(spec)
return instance
with this code, I am getting the following result but not as expected
{
"name": "Appel watch series",
"specifications": [
{
"name": "Test Data",
"attributes": []
},
{
"name": "Test Data comn",
"attributes": []
},
{
"name": "Test Spec",
"attributes": []
}
]
}
it cannot write into attributes
I searched for many answers but I did not find or applied some of them, again it did not help me. I am using just ListCreateView in the views. Please is there anybody who can help solve this problem. Thanks in advance!
SOLVED
I am using here ModelSerializer instead I used Serializer and added some changes here my answer and it worked
class AttributeSerializer(serializers.Serializer):
index = serializers.CharField(max_length=200)
value = serializers.CharField(max_length=200)
class SpecNameSerializer(serializers.ModelSerializer):
attributes = AttributeSerializer(many=True)
class Meta:
model = SpecificationName
fields = '__all__'
class ProductSerializer(serializers.ModelSerializer):
specifications = SpecNameSerializer(many=True)
class Meta:
model = Product
fields = ['name', 'category', 'brand', 'price', 'specifications']
def create(self, validated_data):
specs = validated_data.pop('specifications')
instance = Product.objects.create(**validated_data)
for spec in specs:
SpecificationName.objects.create(product=instance, **spec)
attrs = spec.pop('attributes')
for attr in attrs:
Attribute.objects.create(spec_name=spec, **attr)
return instance

RelatedObjectDoesNotExist when nesting data in DRF

I'm trying to serialize a model with nested data for its relationships. The data is returned properly in a GET request but when trying to POST data the following error is returned: api.models.Narration.narrative.RelatedObjectDoesNotExist: Narration has no narrative. I have no interest in POSTing nested data, it only needs to be returned in the GET requests and PKs can be used everywhere else. I have tried to using Meta.depth as well as defining the fields manually, both of which return the same exception. Code is below, any help is appreciated.
# serializers.py
class NarrationSerializer(ModelSerializer):
narrative = NarrativeSerializer(read_only=True)
settings = MapSettingsSerializer(read_only=True)
attached_events = CachedDataSerializer(many=True, read_only=True)
class Meta:
model = Narration
fields = "__all__"
# depth = 1 [also doesn't work]
# models.py
class Narration(OrderedModel):
narrative = models.ForeignKey(Narrative, on_delete=models.CASCADE)
title = models.TextField()
description = models.TextField()
date_label = models.CharField(max_length=100)
map_datetime = models.DateTimeField()
attached_events = models.ManyToManyField(CachedData)
img = models.URLField(blank=True, null=True)
video = models.URLField(blank=True, null=True)
settings = models.ForeignKey(MapSettings, on_delete=models.CASCADE)
order_with_respect_to = "narrative"
# views.py
class NarrationViewSet(viewsets.ModelViewSet):
queryset = Narration.objects.all()
serializer_class = NarrationSerializer
POSTed nested data (using PKs results in same exception):
{
"title": "cvxcv",
"description": "cxvxcv",
"date_label": "test",
"map_datetime": "0002-01-01T00:00:00Z",
"img": "",
"video": "",
"narrative": {
"author": "Test Author",
"title": "Test Narrative",
"description": "This is a test narrative.",
"tags": [
"test",
"tags"
]
},
"settings": {
"bbox": {
"type": "MultiPoint",
"coordinates": [
[
0,
0
],
[
1,
1
]
]
},
"zoom_min": 1,
"zoom_max": 12
},
"attached_events": [
{
"event_type": 178561,
"wikidata_id": 1,
"location": {
"type": "Point",
"coordinates": [
0,
0
]
},
"date": "0001-01-01",
"rank": 830700
}
]
}

Django Rest Framework - Get full related objects in list

I'm rather new to Django Rest Framework and I'm trying to use DRF to to serialize a list of (related) objects.
I have the following models:
class Answer(models.Model):
value = models.CharField(max_length=128)
class User(models.Model):
name = models.CharField(max_length=128)
age = models.PositiveIntegerField()
class UserAnswer(models.Model):
user = models.ForeignKey(User)
answer = models.ForeignKey(Answer)
And the result I'm trying to get is in this form:
[
{
"name": "myName1",
"answers": [
{
"value": "myFirstAnswer"
},
{
"value": "mySecondAnswer"
},
{
"value": "myThirdAnswer"
},
]
},
{
"name": "myName2",
"answers": [
{
"value": "myFirstAnswer"
},
{
"value": "mySecondAnswer"
},
{
"value": "myThirdAnswer"
},
]
}
]
I'm trying to do it this way now:
class UserAnswerSerializer(serializers.ModelSerializer):
answers = AllUserAnswersSerializer(many=True, read_only=True)
class Meta:
model = User
fields = ('name', 'answers')
But then I get the following result:
[
{
"name": "myName1"
},
{
"name": "myName2"
}
]
And when I try to do it this way:
class UserAnswerSerializer(serializers.ModelSerializer):
answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = User
fields = ('name', 'answers')
Then i get the following result (an example again):
[
{
"name": "myName1",
"answers": [
1,
2,
3
]
},
{
"name": "myName2",
"answers": [
4,
5,
6
]
}
]
I'm having a hard time making this work, hope someone can show me how to convert the Primary Key's to actual objects!
Thanks!
Remove the explicit definition of the answers field in your serializer and add depth=1. It should look like this:
class UserAnswerSerializer(serializers.ModelSerializer):
class Meta:
depth = 1
model = User
fields = ('name', 'answers')
Info about depth: http://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization

Categories