Django rest framework get all related foreign key - python-2.7

I have two models Organization and Departments. I would like to get all the department related particular organization id by using DRF, how can I do this
class Organization(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
class Departments(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
email= models.CharField(max_length=30, unique=True)
phone= models.CharField(max_length=30)
org_linked=models.ForeignKey(Organization)
user_linked=models.ForeignKey(User)
class OrganizationAndDepartmentSerializer(serializers.ModelSerializer):
org_department=facilitesntSerializer(many=True)
class Meta:
model = facilites
fields=('org_department',)
class OrganizationAndDepartmentViewSet(viewsets.ModelViewSet):
serializer_class =OrganizationAndDepartmentSerializer

If you want the full nested representation; declare a nested serializer as follows:
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Departments
fields = ('__all__')
class OrganizationSerializer(serializers.ModelSerializer):
departments = DepartmentsSerializer(many=True, source='org_linked_set', read_only=True)
class Meta:
model = Organization
fields = (
'name',
'description',
'departments'
)

Related

How to include ManyToMany Fields in DjangoRestFramework?

class EntityServiceSerializer(serializers.ModelSerializer):
class Meta:
model = Service
fields = '__all__'
class EntityCreateSerializer(serializers.ModelSerializer):
entity_service = EntityServiceSerializerThrough(read_only=True, source='serviceschedule_set', many=True)
class Meta:
model = Entity
fields = '__all__'
Model looks like this
class Entity(models.Model):
entity_service = models.ManyToManyField(Service, through='ServiceSchedule')
class ServiceSchedule(models.Model):
service = models.ForeignKey(Service, on_delete=models.CASCADE)
entity = models.ForeignKey(Entity, on_delete=models.CASCADE)
class Service(models.Model):
service_name = models.CharField(max_length=256, null=True)
slug = models.SlugField(max_length=128, unique=True, null=False, editable=False)
created_at = models.DateTimeField(editable=False, default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
animal = models.ForeignKey(Animal, on_delete=models.CASCADE, default=None)
I have these serializers (there are more fields in entity model, but they're irrelevant since the only problem i have is with the Many2Many)
The thing is, when i put in body "entity_service": [1,2] in the response i still get = []. Even though i have in my database Services with pk 1,2,3,4.
Do you know how can i make it work?
Try it without a source as the field name is the same as the model field name
class EntityCreateSerializer(serializers.ModelSerializer):
entity_service = EntityServiceSerializerThrough(read_only=True, many=True)
class Meta:
model = Entity
fields = '__all__'

making an api to show the books of an auther in django rest framework

I have two models in my project: Author and Book. Each book has a foreignkey that points to the author of the book.
I want to write an api which retrieves and instance of an Author and shows the details of that specific person.
The problem is that I don't know how to include that said person's books in my API.
This is my models.py:
class Book(models.Model):
title = models.CharField(max_length=150)
rating = models.IntegerField(default=0, validators=[MaxValueValidator(10), MinValueValidator(0),])
summary = models.TextField()
author = models.ForeignKey(Author, null=True, on_delete=models.SET_NULL)
class Author(models.Model):
authorID = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
dateOfBirth = models.DateField(null=True)
nationality = models.CharField(null=True, max_length=255)
AND this is the method that didn't work for me:
# Serializers.py
class AuthorRetrieveSerializer(serializers.ModelSerializer):
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
bookDetails = BookSerializer(read_only=True, many=True)
class Meta:
model = Author
fields = ('name', 'dateOfBirth', 'nationality', 'bookDetails')
# Views.py
class AuthorRetrieveViewSet(RetrieveUpdateDestroyAPIView):
permission_classes = (AllowAny,)
serializer_class = serializers.AuthorRetrieveSerializer
queryset = Author.objects.all()
lookup_field = 'authorID'
def get_queryset(self):
return self.queryset
This code retrieves the Author details successfully but doesn't give me their Books.
Have you tried specifying the source on the serializer?
# Serializers.py
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
class AuthorRetrieveSerializer(serializers.ModelSerializer):
bookDetails = BookSerializer(read_only=True, many=True, source="book_set")#correction here
class Meta:
model = Author
fields = ('name', 'dateOfBirth', 'nationality', 'bookDetails')

How do I filter data with two parameter from two different Django models

I want to create a JSON object which will
Search the particular Projects from the model "EmpProject" by a specific emp_id
Search whose project status is "Pending" from the model "Project" with the help of (1.) Search result
I am using JSON Parser (no models or generic view)
Models
Below are my models I have not use many to many field instead I created a Intermediate Table if the solution is also possible by using manytomanyfield than also suggest
class Employee(models.Model):
employeeid = models.IntegerField()
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone_no = models.CharField(max_length=10)
date_of_birth = models.DateField()
email = models.EmailField(unique=True)
password = models.CharField(max_length=50)
designation = models.CharField(max_length=50)
dept_id = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
ordering = ('id',)
def __str__(self):
return self.emp_name
class Project(models.Model):
projectname = models.CharField(max_length=50, unique=True,)
project_status = models.CharField(max_length=50)
description = models.TextField()
start_date = models.DateField(auto_now_add=True)
due_date = models.DateField()
class Meta:
ordering = ('id',)
def __str__(self):
return self.projectname
class EmpProject(models.Model):
emp_id = models.ForeignKey(Employee,on_delete=models.SET_NULL, null=True, blank=True)
project_id = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
unique_together = [['emp_id','project_id']]
ordering = ('project_id',)
def __str__(self):
return self.emp_id
Serializer
class EmployeeSerializer(serializers.ModelSerializer):
dept_id = serializers.SlugRelatedField(queryset=Department.objects.all(), slug_field='dept_name')
class Meta:
model = Employee
fields = [
'id',
'employeeid',
'first_name',
'last_name',
'phone_no',
'date_of_birth',
'email',
'password',
'designation',
'dept_id',
]
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = [
'id',
'projectname',
'project_status',
'description',
'start_date',
'due_date' ,
]
class EmpProjectSerializer(serializers.ModelSerializer):
emp_id=serializers.SlugRelatedField(queryset=Employee.objects.all(),slug_field='employeeid')
project_id=serializers.SlugRelatedField(queryset=Project.objects.all(),slug_field='projectname')
class Meta:
model = EmpProject
fields = [
'emp_id',
'project_id',
]
You can try something like this:
Project.objects.filter(id__in=EmpProject.objects.filter(id__in=emp_id).values("project_id"), project_status="Pending")
Few points worth mentioning:
It's good idea to use a intermediate table when we want to have extra data related to association. But for that kindly have a look at through attribute supported in ManyToManyField https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.ManyToManyField.through
project_status is CharField, I think you should consider ChoiceField, charfield may introduce lots of dirty data in database.

Django REST Framework join table results in attribute exception

I am building an API in Django using REST Framework but am running into an issue.
Serializers:
class SquadSerializer(serializers.Serializer):
class Meta:
model = Squad
fields = ('name')
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(style={'base_template': 'textarea.html'})
class MembershipSerializer(serializers.Serializer):
class Meta:
model = Membership
fields = ('employee_id', 'squad_id')
squad = SquadSerializer()
employee = EmployeeSerializer()
class EmployeeSerializer(serializers.HyperlinkedModelSerializer):
habitat = HabitatSerializer()
class Meta:
model = Employee
fields = ('id', 'first_name', 'last_name', 'function',
'start_date', 'end_date', 'visible_site', 'habitat')
Models:
class Employee(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
function = models.CharField(max_length=50)
start_date = models.DateField()
end_date = models.DateField(null=True, blank=True)
visible_site = models.BooleanField()
habitat = models.ForeignKey(Habitat, on_delete=models.SET_NULL, null=True, blank=True)
class Squad(models.Model):
name = models.TextField(max_length=40)
class Membership(models.Model):
class Meta:
unique_together = (('employee', 'squad'))
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, null=False, blank=True, default=1)
squad = models.ForeignKey(Squad, on_delete=models.CASCADE, null=False, blank=True, default=1)
The problem is that I keep running into this error:
AttributeError: Got AttributeError when attempting to get a value for field `name` on serializer `SquadSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Membership` instance.
Original exception text was: 'Membership' object has no attribute 'name'.
When executing this test (and a couple others)
def test_membership_serializer_id_name_field_content(self):
"""
The name field of a squad should contain an id
"""
serializer = create_membership_serializer(self.membership, '')
self.assertEqual(serializer.data['id'], self.membership.id)
I've seen multipe people with the same issues here on Stack Overflow but the often suggest solution (to add many=True to SquadSerializer() and EmployeeSerializer()) doesn't work. I hope anyone here has any knowledge on why this happens.
If you want to map your seriailizer to your model, you should use ModelSerializer. In tupple, if it has only one value, you should write it as (1,) not (1). Your SquadSerializer should be like
class SquadSerializer(serializers.ModelSerializer):
class Meta:
model = Squad
fields = ('name',) # or ('id', 'name')
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(style={'base_template': 'textarea.html'})
Your MembershipSerializer should be like
class MembershipSerializer(serializers.ModelSerializer):
class Meta:
model = Membership
fields = ('employee', 'squad')
squad = SquadSerializer()
employee = EmployeeSerializer()

Django rest framework get one to many relationship data

I have a django model named Event, which references Customer model.
event_name = models.CharField(max_length=200, unique=True)
customer = models.ForeignKey(customer_models.Customer, db_index=True,
on_delete=models.SET_NULL,
related_name='customer_events', null=True)
event_location = models.CharField(max_length=200, default='')
event_date = models.DateField()
I need to get the customer list along with the latest event name for each user in the API.
Customer serializers.py file is
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
Customer views.py file is
class CustomerViewSet(viewsets.ModelViewSet):
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
How can I accomplish this?
In your Customer model you can have a property that returns the latest event name for a Customer instance:
class Customer(models.Model):
...
#property
def latest_event_name(self):
"""Return latest event name."""
# self.customer_events.order_by('event_date').last()
latest_event = self.customer_events.order_by('-event_date').first()
return latest_event.event_name if latest_event else None
In your serializer you can then add a ReadOnlyField for latest_event_name:
class CustomerSerializer(serializers.ModelSerializer):
latest_event_name = serializers.ReadOnlyField()
class Meta:
model = Customer
fields = '__all__'