Django. Difficult queryset - python

I have user like this:
{
"name": "test"
"parent_users": [
1,
2
]
}
I need to display the user "name": "test" two times becouse he has two parents, for example i need to display the user "name": "test" like this:
{
"name": "test"
"parent_user": 1
}
{
"name": "test"
"parent_user": 2
}
My serializer
class CommitmentListSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id',
'email',
'first_name',
'last_name',
'parent_user',)
I cant understand how i can to create quesryset for this
UPD
user model
class User(PermissionsMixin):
id = models.CharField(primary_key=True,
unique=True,
max_length=128,
default=uuid.uuid4,
editable=False)
email = models.EmailField(
_('email address'),
max_length=100,
unique=True,
null=True,
blank=True,
default=None,
error_messages={'unique': _("A user with that email already exists.")}
)
...
# another fields
...
parent_user = models.ManyToManyField('self',
unique=False,
symmetrical=False,
blank=True)
...

Related

Unable to populate images in Django Rest Serializer

I'm developing a REST API using Django Rest Framework but I'm unable to populate image in Feed Serializer
Django Version: 3.1.7
Python Version: 3.9.2
Models:
class User(AbstractUser):
age = models.PositiveIntegerField(null=True)
address = models.TextField(null=True)
email = models.EmailField(_('email address'), unique=True, null=False)
first_name = models.CharField(_('first name'), max_length=150, blank=False, null=False)
last_name = models.CharField(_('last name'), max_length=150, blank=False, null=False)
image = models.ImageField(upload_to='storage', null=True)
class Feed(models.Model):
description = models.TextField()
likes_count = models.PositiveIntegerField(default=0, null=True)
comments_count = models.PositiveIntegerField(default=0, null=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
tags = models.ManyToManyField(User, related_name='tags', blank=True)
class FeedImage(models.Model):
path = models.ImageField(upload_to='storage', null=False)
post = models.ForeignKey(Feed, on_delete=models.CASCADE, null=False, default='')
Serializers:
class FeedUserSerializer(ModelSerializer):
class Meta:
model = User
fields = ('id', 'first_name', 'last_name', 'image')
class FeedImageSerializer(serializers.ModelSerializer):
class Meta:
model = FeedImage
fields = ('id', 'path', 'post')
class FeedSerializer(ModelSerializer):
user = FeedUserSerializer()
images = FeedImageSerializer(many=True, read_only=True)
class Meta:
model = Feed
fields = ('id', 'description', 'comments_count', 'likes_count', 'updated_at', 'created_at',
'tags', 'images', 'user')
View:
class FeedsListView(generics.ListAPIView):
queryset = Feed.objects.all()
return FeedSerializer
Problem: I get this result without images
[{
"id": 1,
"description": "Hello world",
"comments_count": 0,
"likes_count": 0,
"updated_at": "2021-04-26T03:01:44.219235Z",
"created_at": "2021-04-26T03:01:44.219235Z",
"tags": [],
"user": {
"id": 1,
"first_name": "ZAIN",
"last_name": "REHMAN",
"image": "http://192.168.88.28:8000/storage/1_Facebook_1.jpg"
}
}]
Expected Output:
[{
"id": 1,
"description": "Hello world",
"comments_count": 0,
"likes_count": 0,
"updated_at": "2021-04-26T03:01:44.219235Z",
"created_at": "2021-04-26T03:01:44.219235Z",
"tags": [],
"user": {
"id": 1,
"first_name": "abc_first",
"last_name": "cdef_last",
"image": "http://192.168.88.28:8000/storage/1_Facebook_1.jpg"
},
"images": [
{
"id": 1,
"post": "1",
"path": "imagelocation"
},
{
"id": 2,
"post": "1",
"path": "imagelocation 2"
}
]
}]
Any solution or any workaround will be appreciated.
Ignore this: Bulk text to resolve StackOverflow problem
industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
You can use SerializerMethodField for this.
class FeedSerializer(ModelSerializer):
images = serializers.SerializerMethodField()
class Meta:
model = Feed
fields = ('id', 'description', 'comments_count', 'likes_count', 'updated_at', 'created_at',
'tags', 'images', 'user')
def get_images(self, obj):
return obj.feedimage_set.all().values('id', 'path', 'post')

Django Serializer's Source argument is not working

I am trying to get all the bills and their customer-related details (i.e. 'customer_code', 'email' etc.) with it.
However, source='user.customer_code does not seem to have any effect at all. What am I missing?
I have been following along this:
this stackoverflow post with no luck.
My two models:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(db_index=True, unique=True, max_length=200)
customer_code = models.CharField(max_length=300, blank=True, null=True, default=None)
class Bill(models.Model):
customer = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True, related_name="customer_bill"
)
payable_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
View:
class BillView(APIView):
def get(self, request, format=None):
q = Bill.objects.all().select_related('customer')
s = BillSerializer(q, many=True)
return JsonResponse({
"bill": s.data
})
Serializer:
class BillSerializer(serializers.ModelSerializer):
customer_code = serializers.CharField(source='user.customer_code', read_only=True)
class Meta:
model = Bill
fields = ('id','payable_amount','customer_code') # binding customer_code here
Current Output:
"bill": [
{
"id": 1,
"payable_amount": "1000.00"
},
{
"id": 2,
"payable_amount": "2000.00"
}
]
Expected Result:
"bill": [
{
"id": 1,
"payable_amount": "1000.00",
"customer_code": "CUS10001" # want this to be attached
},
{
"id": 2,
"payable_amount": "2000.00",
"customer_code": "CUS10002" # want this to be attached
}
]

Django : Add JSON POST data into the database

I'm trying to make an API for a butcher.
With this API and the website that I will build by the next, the client will be able to make his order remotly.
Here is my probleme.
With the order form, the client send me JSON data like here :
{
"user": 8,
"orderDay": "2020-06-24",
"deliveryDay": "2020-06-30",
"deliveryAddress": "Place des FĂȘtes",
"comment": "",
"orderDetail":
[
{
"product": 2,
"byProduct": 2,
"quantity": 43
},
{
"product": 3,
"byProduct": 3,
"quantity": 5
}
]
}
These data must be saved in the database.
These are the models that I use : models.py
class order(models.Model):
user = models.ForeignKey(memberArea, on_delete=models.CASCADE)
comment = models.TextField(null=True, blank=True)
orderDay = models.DateTimeField(auto_now_add=True)
deliveryDay = models.DateField()
deliveryAddress = models.CharField(max_length=255)
state = models.CharField(max_length=255)
price = models.TextField(null=True, blank=True)
response = models.TextField(null=True, blank=True)
class orderDetail(models.Model):
order = models.ForeignKey(order, on_delete=models.CASCADE)
product = models.ForeignKey(product, on_delete=models.CASCADE)
byProduct = models.ForeignKey(byProduct, on_delete=models.CASCADE)
quantity = models.CharField(max_length=255)
class product(models.Model):
name = models.CharField(max_length=255)
prix_uni = models.TextField(null=True, blank=True)
prix_kg = models.TextField(null=True, blank=True)
dispo = models.BooleanField(null=True, blank=True)
category = models.ForeignKey(category, on_delete=models.CASCADE)
redu = models.TextField(null=True, blank=True)
class byProduct(models.Model):
product = models.ForeignKey(product, on_delete = models.CASCADE)
name = models.CharField(max_length=255)
I make a serializer file like this serializer.py
class orderDetailSerializer(serializers.ModelSerializer):
order = serializers.PrimaryKeyRelatedField(many=False, queryset = order.objects.all())
class Meta:
model = orderDetail
fields = '__all__'
class OrderSerializer(serializers.ModelSerializer):
orderDetail = orderDetailSerializer(many=True)
class Meta:
model = order
fields = ['user', 'comment', 'deliveryAddress', 'deliveryDay', 'orderDetail']
def create(self, validated_data):
order_detail_data = validated_data.pop('orderDetail')
new_order = order.objects.create(**validated_data)
new_order.save()
for product in order_detail_data:
order_detail = orderDetail.objects.create(order=new_order, **product)
new_order.orderDetail.add(order_detail.id)
return new_order
And this is my view : views.py:
#Make an order
#api_view(['POST'])
def order(request, format=None):
if request.method == 'POST':
serializer = OrderSerializer(data=request.data)
data = {}
if serializer.is_valid():
serializer.save()
data['response'] = "Your order went well"
return Response(data)
return Response(serializer.errors)
When I try to run my code, it tells me that the order data is missing :
{
"orderDetail": [
{
"order": [
"This field is required."
]
},
{
"order": [
"This field is required."
]
}
]
}
I don't know how to add this because the order_id that I need is created at the same time that the orderDetail.
Thank's by advance for helping me.
you should make order field readonly in orderDetailSerializer:
class orderDetailSerializer(serializers.ModelSerializer):
class Meta:
model = orderDetail
fields = '__all__'
read_only_fields = ('order',)

Getting null for my profile serializer data instead of actual data

I am using Django-rest-auth to authenticate my users, that works well. how my model is set up is that I have the custom user model for authentication and I also have a profile model that gets created with a signal whenever a user is created.
I want that when the users are fetched in its URL, the profile for that user is also displayed, and I have passed through the serializer.
THE PROBLEM: I am getting null instead of the actual data
my models.py (I didnt include some models like the user managers, skill, e.t.c as i felt they werent relevant)
class User(AbstractBaseUser, PermissionsMixin):
username = None
email = models.EmailField(max_length=254, unique=True)
fullname = models.CharField(max_length=250)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['fullname']
objects = UserManager()
class Profile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
bio = models.TextField(max_length=500, blank=True, null=True)
profile_photo = models.CharField(blank=True, max_length=300, null=True)
skills = models.ManyToManyField(Skill, related_name='skills')
sex = models.CharField(max_length=1, choices=SEX, blank=True, null=True)
type_of_body = models.CharField(max_length=8, choices=BODYTYPE, blank=True, null=True)
feet = models.PositiveIntegerField(blank=True, null=True)
inches = models.PositiveIntegerField(blank=True, null=True)
lives_in = models.CharField(max_length=50, blank=True, null=True)
updated_on = models.DateTimeField(auto_now_add=True)
the serializers.py code
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = "__all__"
read_only_fields = ('pk',)
class CustomUserDetailsSerializer(serializers.ModelSerializer):
profiles = ProfileSerializer(read_only=True)
class Meta:
model = User
fields = ('pk', 'email', 'fullname', 'profiles')
read_only_fields = ('email', 'fullname', 'profiles')
view.py
class ListUsersView(APIView):
permission_classes = [AllowAny]
def get(self, request):
user = User.objects.all()
serializer = CustomUserDetailsSerializer(user, many=True)
return Response(serializer.data)
urls.py
url(r'^list-users/$', ListUsersView.as_view(), name='list-users'),
the JSON response I get
[
{
"pk": 1,
"email": "opeyemiodedeyi#gmail.com",
"fullname": "opeyemi odedeyi",
"profiles": {
"date_of_birth": null,
"bio": null,
"profile_photo": null,
"sex": null,
"type_of_body": null,
"feet": null,
"inches": null,
"lives_in": null
}
}
]
how do I get the profiles to show in the response?
I guess the problem is in your CustomUserDetailsSerializer. you have one-to-many relationship with User and Profile, but you are not explicitly telling it in your profiles attribute of the serializer. You have to pass many=True argument to the ProfileSerializer:
class CustomUserDetailsSerializer(serializers.ModelSerializer):
profiles = ProfileSerializer(many=True, read_only=True)
class Meta:
model = User
fields = ('pk', 'email', 'fullname', 'profiles')
read_only_fields = ('email', 'fullname', 'profiles')
But I am curious why you are using one-to-many relationship for that. You could use OneToOneField which explicitly tells that one user can only have one profile. But I am not familiar with your situation, so that is only my advice.

Django Rest Framework foreign key nesting

I am trying to nest my Users table inside my Relationships table. So instead of this:
[
{
"user": 1,
"related_user": 2,
"relationship": "followed_by"
}
]
I am trying to get this:
[
{
"user": {
"username": "user1",
"name": "User 1",
"email": "bla",
"phone": "bla",
"date_joined": "2017-11-01T21:34:13.101256Z"
},
"related_user": {
"username": "user2",
"name": "User 2",
"email": "bla",
"phone": "bla",
"date_joined": "2017-11-01T21:34:13.101256Z"
},
"relationship": "followed_by"
}
]
I looked up tutorials and I tried adding serializers.RelatedField , UserSerializer(many=true, read-only=true) etc. but nothing worked
Models.py
class User(models.Model):
username = models.CharField(max_length=255)
name = models.CharField(max_length=255)
email = models.CharField(max_length=255)
phone = models.CharField(max_length=255)
date_joined = models.DateTimeField(auto_now_add=True, blank=True)
def __str__(self):
return str(self.pk) + ", " + self.username
RELATIONSHIP_CHOICE = [
("follows", "follows"),
("followed_by", "followed_by"),
("none", "none"),
]
class Relationship(models.Model):
user = models.ForeignKey(User, related_name="primary_user", null=True)
related_user = models.ForeignKey(User, related_name="related_user", null=True)
relationship = models.CharField(max_length=40, choices=RELATIONSHIP_CHOICE, default=RELATIONSHIP_CHOICE[0])
Serializers.py
from rest_framework import serializers
from . import models
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = models.User
fields = (
'username',
'name',
'email',
'phone',
'date_joined',
)
class RelationshipSerializer(serializers.ModelSerializer):
related_user = UserSerializer(many=True)
class Meta:
model = models.Relationship
fields = (
'user',
'related_user',
'relationship',
'related_user'
)
I tried to add related user to my serializer but it didnt work. I am getting an error: 'User' object is not iterable
Any help is appreciated.
class RelationshipSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
related_user = UserSerializer(read_only=True)
class Meta:
model = models.Relationship
fields = (
'user',
'related_user',
'relationship'
)
user = UserSerializer(read_only=True, many=True) is for manytomany field,user = UserSerializer(read_only=True) is for ForeignKey field.

Categories