Serializers in Foreign Key Django - django

i need to get information from Reservation, ReservationDetails and Product, but just get Reservation and ReservationDetails
i have 3 models
class Reservation(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
userReservation = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
dateStart = models.DateTimeField(null=False, blank=False, default=datetime.now)
dateFinish = models.DateTimeField(null=False, blank=False, default=datetime.now)
date_Created = models.DateTimeField(auto_now_add=True)
date_Modified = models.DateTimeField(auto_now=True, db_index=True)
def __str__(self):
return str(self.id)
class DetailsReservation(models.Model):
Reservation = models.ForeignKey(Reservation, blank=False, on_delete=models.CASCADE, null=True, related_name='reservation_details')
product = models.ForeignKey(Product, blank=False, on_delete=models.CASCADE, null=True, related_name='products_reservation')
Quantity = models.IntegerField(null=False, blank=False, default=0)
userbyReserva = models.ForeignKey(User, editable=False, on_delete=models.CASCADE, default=1)
class Product(models.Model):
product_Description = models.CharField(max_length=255)
Quantity = models.IntegerField(null=False, blank=False, default=0)
Quantity_Max_Reservation = models.IntegerField(null=False, blank=False, default=0)
product_Comments = models.CharField(max_length=255)
size = models.CharField(max_length=10, null=True)
product_Status = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='products')
date_Created = models.DateTimeField(default=datetime.now, blank=True)
date_Modified = models.DateTimeField(default=datetime.now, blank=True)
And i tried to create serializers
class ReservationDetailsSerializers(serializers.ModelSerializer):
products = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(), required=False)
class Meta:
model= DetailsReservation
fields = ['Reservation', 'Quantity', 'userbyReserva', 'products']
class ReservationDetailsListSerializer(serializers.ModelSerializer):
reservation_details = ReservationDetailsSerializers(many=True)
class Meta:
model = Reservation
fields = ['id', 'userReservation', 'dateStart', 'dateFinish', 'reservation_details']
but the response does not show this field
[
{
"id": "6d87ba1c-61bc-41bd-80c8-31a51df8d32f",
"userReservation": 1,
"dateStart": "2018-09-16T17:19:34-05:00",
"dateFinish": "2018-09-16T17:19:35-05:00",
"reservation_details": [
{
"Reservation": "6d87ba1c-61bc-41bd-80c8-31a51df8d32f",
"Quantity": 1,
"userbyReserva": 1
>>"here should show this information product"
}
]
},
{
"id": "0ed26395-2579-4c40-9a63-460f5095ac51",
"userReservation": 2,
"dateStart": "2018-09-16T19:21:24-05:00",
"dateFinish": "2018-09-16T19:21:24-05:00",
"reservation_details": [
{
"Reservation": "0ed26395-2579-4c40-9a63-460f5095ac51",
"Quantity": 1,
"userbyReserva": 2
}
]
}
]
and it is my views.py
class getAllReservationDetails(generics.ListCreateAPIView):
queryset = Reservation.objects.prefetch_related('reservation_details')
print(queryset.query)
serializer_class = ReservationDetailsListSerializer
def get_object(self):
queryset = self.queryset()
obj = get_object_or_404(queryset)
return obj
I review this Link, but i don't know, why doesn't show the information product.
But, that is not working as I wanted.
What should I do?

Did you try creating a serializer for the Product model and use it on the ReservationDetailsSerializers?
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
class ReservationDetailsSerializers(serializers.ModelSerializer):
products = ProductSerializer(source='product', required=False)
class Meta:
model= DetailsReservation
fields = ['Reservation', 'Quantity', 'userbyReserva', 'products']
You can find more about this topic on Specifying nested serialization

The DetailsReservation model has not attribute products, but it has product. So remove the "s" from products or use source = 'product' in ReservationDetailsSerializers serializer
Method - 1 : removal of "s"
class ReservationDetailsSerializers(serializers.ModelSerializer):
product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(), required=False)
class Meta:
model= DetailsReservation
fields = ['Reservation', 'Quantity', 'userbyReserva', 'product']
Method - 2 : speciying source argument
class ReservationDetailsSerializers(serializers.ModelSerializer):
products = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(),
required=False, source='product')
class Meta:
model = DetailsReservation
fields = ['Reservation', 'Quantity', 'userbyReserva', 'products']
UPDATE
I think you need nested serializer representation. If so, you've to define a seperate serializer (say ProductSerializer) and add it to ReservationDetailsSerializers instead of serializers.PrimaryKeyRelatedField()
#new serializer class
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__' # you can specify the fields here
Hence Method-1 become
class ReservationDetailsSerializers(serializers.ModelSerializer):
product = ProductSerializer(required=False)
class Meta:
model= DetailsReservation
fields = ['Reservation', 'Quantity', 'userbyReserva', 'product']
and the Method-2 become
class ReservationDetailsSerializers(serializers.ModelSerializer):
products = ProductSerializer(required=False, source='product')
class Meta:
model = DetailsReservation
fields = ['Reservation', 'Quantity', 'userbyReserva', 'products']

Related

Django serializer data

I need to get value of basket in 'title' not in 'id'.
How can I do this? How can I get a value of 'title' from 'Position' model in another 'Client' model using ManyToManyField. It automatically transmits ID and the 'title' is required
I have tried many ways but... It must be easy, but i search info 2 days
class Position(models.Model):
title = models.CharField(max_length=150, verbose_name='Title')
slug = models.SlugField(max_length=100, unique=True, db_index=True, verbose_name='URL')
description = models.CharField(max_length=500, verbose_name='Describe')
photo = models.ImageField(upload_to="photos/%Y/%m/", verbose_name='Photo', null=True)
price = models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Price')
date_create = models.DateTimeField(auto_now_add=True, verbose_name='Date create')
date_update = models.DateTimeField(auto_now=True, verbose_name='Date update')
is_published = models.BooleanField(default=True, verbose_name='Is published')
in_stock = models.BooleanField(default=True, verbose_name='In stock')
class Client(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
basket = models.ManyToManyField('Position', default=None, blank=True, related_name='basket')
def __str__(self):
return f'{self.user.username}, id-{self.user.id}'
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = "__all__"
class ClientViewSet(viewsets.ModelViewSet):
serializer_class = ClientSerializer
permission_classes = (IsOwnerOrReadOnly,)
def get_queryset(self):
pk = self.kwargs.get('pk')
# need a list of objects, not an one
return Client.objects.filter(pk=pk)
result:
{
"id": 1,
"user": 1,
"basket": [
1
]
}
need something like this - "basket":['monitor','keyboard']
You can use the PositionSerializer to get the title of each Position object in the Client's basket ManyToManyField.
class PositionSerializer(serializers.ModelSerializer):
class Meta:
model = Position
fields = ('title',)
class ClientSerializer(serializers.ModelSerializer):
basket = PositionSerializer(many=True, read_only=True)
class Meta:
model = Client
fields = "__all__"

how to use django Serializer or signal to add object in database?

I create ticket , ticketflow , ticketstate , tickettype models
i need a serializer or signal that when user create ticket programmatically add ticketflow object and set state of ticket to submited or something else
Here is my models
class TicketType(models.Model):
title = models.CharField(max_length=255, blank=False, unique=True, null=False)
def __str__(self):
return self.title
class TicketState(models.Model):
title = models.CharField(max_length=255, blank=False, unique=True, null=False)
def __str__(self):
return self.title
class Ticket(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4 , editable=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
ticket_type = models.ForeignKey(TicketType,on_delete=models.CASCADE , default=1)
title = models.CharField(max_length=255, blank=False, null=False)
message = models.TextField()
attachment = models.FileField(upload_to='uploads/tickets/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx','zip','jpg','png'])], blank=True)
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
class TicketFlow(models.Model):
uuid = models.UUIDField(default=uuid4, editable=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
ticket = models.ForeignKey(Ticket,on_delete=models.CASCADE , related_name='ticketflow')
ticket_state = models.ForeignKey(TicketState,on_delete=models.CASCADE , default=1 , related_name='ticketstate')
message = models.TextField()
attachment = models.FileField(upload_to='uploads/tickets/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx','zip','jpg','png'])], blank=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now= True)
class Meta:
ordering = ['-created_on']
here is my serializers
class TicketTypeSerializer(serializers.ModelSerializer):
class Meta:
model = TicketType
fields = ('id','title',)
class TicketStateSerializer(serializers.ModelSerializer):
class Meta:
model = TicketState
fields = ('id','title',)
class TicketSerializer(serializers.ModelSerializer):
class Meta:
model = Ticket
fields = ['id' , 'author', 'ticket_type','title' ,'message' , 'attachment' , 'created_on']
class TicketFlowSerializer(serializers.ModelSerializer):
class Meta:
model = TicketFlow
fields = ['author', 'ticket_state', 'message', 'attachment', 'created_on', 'updated_on']
It'll be great if someone can help me out in this. how can i create signal or override create method in serializers
You probably want your "state" field to be read-only in the serializer, this way it can only be changed programmatically, and in the model set a default value with default='pending'.
Then you can override the update method in a Serializer (see the doc here):
def update(self, instance, validated_data):
validated_data['state'] = 'edited'
return super(MySerializer, self).update(instance, validated_data)

I have question about Django REST Filter ID ForeignKey

How Can filter Org.id in Department
simple:
{ id: 1, name: ITDepart, description: itdeapart, org: 43}
{ id:2, name: ITDepart, description: itdeapart, org: 42 }
I have the following models.py:
Organization model:
class Organization(models.Model):
user = models.ForeignKey(User,, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100, blank=True)
description = models.TextField(max_length=500, blank=True)
created_date = models.DateTimeField(auto_now_add=True, null=True)
logo = models.ImageField(upload_to=upload_update_image, blank=True, null=True)
slug = models.SlugField(blank=True)
Department model:
class Department(models.Model):
org = models.ForeignKey(Organization, on_delete=models.CASCADE, null=True , blank=True)
name = models.CharField(max_length=50)
description = models.TextField(max_length=300)
slug = models.SlugField(max_length=100, null=True, blank=True)
I have Serializaer:
class OrgSerializer(serializers.ModelSerializer):
logo = Base64ImageField(max_length=None, use_url=True)
class Meta:
model = Organization
fields = [
'id', 'name', 'description','slug', 'user', 'created_date', 'logo']
class DepartmentSerailizer(serializers.ModelSerializer):
class Meta:
model = Department
fields = ['id', 'name', 'description', 'slug' , 'org']
I Have Viewset:
class OrgViewset(viewsets.ModelViewSet):
authentication_classes = ( TokenAuthentication, )
permission_classes = (IsAuthenticated, )
queryset = Organization.objects.all()
serializer_class = OrgSerializer
class DepartmentViewset(viewsets.ModelViewSet):
authentication_classes = ( TokenAuthentication, )
permission_classes = (IsAuthenticated,)
queryset = Department.objects.all()
serializer_class = DepartmentSerailizer
lookup_field = 'pk'
Either you can add a default ordering at your model
class Organization(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
....
class Meta:
ordering = ['-pk'] # descending
or when you filter Department
qs = Department.objects.filter(...).order_by('org__pk') # ascending
qs = Department.objects.order_by('org__pk') # ascending without filter
However, ordering django´s default-pk doesn´t make sense. If you are using default PrimaryKey of django, it has already a ascending ordering by default.

how to use RelatedField in Django rest framework?

I have problem with Django restframe work i have 2 table that one of them is a foreign key to another i have used RelatedField in serializer but i get an error:'Relational field must provide a queryset argument,
can someone help me in this case
my code is as below:
class DocTable(models.Model):
project = models.CharField(max_length=1000, null=True, blank=True)
document_no = models.CharField(max_length=1000, null=True, blank=True)
document_title = models.TextField(null=True, default='', blank=True)
class PlanTable(models.Model):
document = models.ForeignKey(DocTable, on_delete=models.CASCADE, related_name='doctable')
work_type = models.CharField(max_length=1000, null=True, blank=True)
description_work = models.TextField(null=True, default='', blank=True)
serializers.py
class DocTableSerializer(serializers.ModelSerializer):
doctable = serializers.RelatedField(many=True)
class Meta:
model = DocTable
fields = ['pk', 'project', 'document_no', 'doctable']
read_only_fields = ['pk']
class PlanTableSerializer(serializers.ModelSerializer):
class Meta:
model = PlanTable
fields = ['pk', 'document', 'work_type', 'description_work']
read_only_fields = ['pk']
views.py
class DocTableListView(generics.ListAPIView):
lookup_field = 'pk'
serializer_class = DocTableSerializer
def get_queryset(self):
return PlanTable.objects.all()
def get_object(self):
pk = self.kwargs.get('pk')
return PlanTable.objects.get(pk=pk)
You have to provide queryset in RelatedField like this.
class DocTableSerializer(serializers.ModelSerializer):
doctable = serializers.RelatedField(many=True, queryset=DocTable.objects.all())
Or if you only want to use this related field for retrieving data, you can mark it as read only
doctable = serializers.RelatedField(many=True, read_only=True)

Django rest fetch data from bridge model

I want to get all the user details and list of all the roles against the
user details model
My Models
class UserDetail(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,
related_name='userdetail_user', default='111')
cn = models.CharField(max_length=200)
sn = models.CharField(max_length=200)
u_id = models.CharField(max_length=200)
display_name_cn = models.CharField(max_length=200)
display_name_en = models.CharField(max_length=200)
given_name = models.CharField(max_length=200)
employee_number = models.CharField(max_length=200)
email = models.CharField(max_length=200)
created_at = models.DateTimeField(default=datetime.now, blank=True)
last_login = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.given_name
class Role(models.Model):
title = models.CharField(max_length=20)
description = models.CharField(max_length=200)
created_at = models.DateTimeField(default=datetime.now, blank=True)
last_updated = models.DateTimeField(default=datetime.now, blank=True)
status = models.BooleanField(default=True)
def __str__(self):
return self.title
class UserRole(models.Model):
userdetail = models.ForeignKey(UserDetail, on_delete=models.CASCADE,
related_name='userrole_userdetail')
role = models.ForeignKey(Role, on_delete=models.CASCADE)
approver = models.ForeignKey(UserDetail, on_delete=models.SET_NULL,
null=True,
related_name='userrole_userdetail_approver')
created_at = models.DateTimeField(default=datetime.now, blank=True)
last_updated = models.DateTimeField(default=datetime.now, blank=True)
status = models.BooleanField(default=True)
My Serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
class UserRoleSerializer(serializers.ModelSerializer):
class Meta:
model = UserRole
fields = (
'id', 'userdetail', 'role', 'approver', 'last_updated', 'status')
depth = 1
def to_representation(self, instance):
representation = super(UserRoleSerializer, self).to_representation(
instance)
representation['userdetail'] = UserDetailSerializer(
instance.userdetail).data
representation['role'] = RoleSerializer(instance.role).data
representation['approver'] = UserDetailSerializer(
instance.approver).data
return representation
class RoleSerializer(serializers.ModelSerializer):
class Meta:
model = Role
fields = ('id', 'title', 'description', 'last_updated', 'status')
class UserDetailSerializer(serializers.ModelSerializer):
user = UserSerializer()
roles = serializers.SerializerMethodField(read_only=True)
class Meta:
model = UserDetail
fields = ('id', 'roles', 'user', 'cn', 'sn', 'u_id', 'display_name_cn',
'display_name_en', 'given_name', 'employee_number', 'email',
'last_login')
lookup_field = 'u_id'
def get_roles(self, obj):
roles = UserRole.objects.filter(userdetail=obj)
return roles
When I try to fetch all the user details it gives me an error
"Object of type 'UserRole' is not JSON serializable".
I have already tried to serialize the list of object fetched inside get_roles method of UserDetailsSerializer but its no help
In your Serializers, you have to replace
roles = serializers.SerializerMethodField(read_only=True)
With
userrole_userdetail = UserRoleSerializer(many=True, read_only=True)
Its because your FK relation name must match the related name given in the model. Also in UserRoleSerializer you do not need the to_representation method.