using foreign key set in django models django rest framework - django

I am having an interesting problem. I am using the ForeignKey call in the relations mananger. I.e. if I want all the objects from a related model known as hamsters the call would be hamsters_set
now here is a working model attached to a serializer everything is working in this implementation.
class SearchCity(models.Model):
city = models.CharField(max_length=200)
class SearchNeighborhood(models.Model):
city = models.ForeignKey(SearchCity, on_delete=models.CASCADE)
neighborhood = models.CharField(max_length=200)
class CityNeighborhoodReadOnlySerializer(serializers.ModelSerializer):
searchneighborhood_set = SearchNeighborhoodSerializer(many=True, read_only=True)
class Meta:
model = SearchCity
fields = ('pk','city','searchneighborhood_set')
read_only_fields =('pk','city', 'searchneighborhood_set')
but with this new model in which I am trying to do the same thing, I am getting an attribute error
class Room(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE)
name = models.CharField(max_length=100, null=True, blank=True)
online = models.BooleanField(default=False)
description = models.CharField(max_length=1000, blank=True, null=True)
privateroom = models.BooleanField(default=False)
semiprivateroom = models.BooleanField(default=False)
seatedcapacity = models.CharField(max_length=10, null=True, blank=True)
standingcapacity = models.CharField(max_length=10, null=True, blank=True)
minimumspend = models.PositiveSmallIntegerField(blank=True, null=True)
surroundsoundamenity = models.BooleanField(default=False)
outdoorseatingamenity = models.BooleanField(default=False)
stageamenity = models.BooleanField(default=False)
televisionamenity = models.BooleanField(default=False)
screenprojectoramenity = models.BooleanField(default=False)
naturallightamenity = models.BooleanField(default=False)
wifiamenity = models.BooleanField(default=False)
wheelchairaccessibleamenity = models.BooleanField(default=False)
cocktailseatingseatingoption = models.BooleanField(default=False)
classroomseatingoption = models.BooleanField(default=False)
ushapeseatingoption = models.BooleanField(default=False)
sixtyroundseatingoption = models.BooleanField(default=False)
boardroomseatingoption = models.BooleanField(default=False)
theaterseatingoption = models.BooleanField(default=False)
hallowsquareseatingoption = models.BooleanField(default=False)
class RoomImage(models.Model):
room = models.ForeignKey(Room, on_delete=models.CASCADE)
order = models.PositiveSmallIntegerField(blank=True, null=True)
imageurl = models.CharField(max_length=200, blank=True, null=True)
class RoomAndImageSerializer(serializers.ModelSerializer):
roomimage_set = RoomImageSerializer(many=True)
class Meta:
model = Room
fields = ('name', 'online', 'description','privateroom','semiprivateroom', 'seatedcapacity', 'standingcapacity','minimumspend','surroundsoundamenity','outdoorseatingamenity','stageamenity','televisionamenity','screenprojectoramenity','naturallightamenity','wifiamenity','wheelchairaccessibleamenity','cocktailseatingseatingoption', 'classroomseatingoption','ushapeseatingoption','sixtyroundseatingoption','boardroomseatingoption','theaterseatingoption','hallowsquareseatingoption','roomimage_set')
AttributeError: Got AttributeError when attempting to get a value for
field roomimage_set on serializer RoomAndImageSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance.
Original exception text was: 'QuerySet' object has no attribute 'roomimage_set'.
rather interesting as the two implementations seem to be the same.
Can anyone catch what I am doing wrong?

You need to set your serializer to readonly
class RoomAndImageSerializer(serializers.ModelSerializer):
roomimage_set = RoomImageSerializer(many=True,read_only=True)
class Meta:
model = Room
fields = ('name', 'online', 'description','privateroom','semiprivateroom', 'seatedcapacity', 'standingcapacity','minimumspend','surroundsoundamenity','outdoorseatingamenity','stageamenity','televisionamenity','screenprojectoramenity','naturallightamenity','wifiamenity','wheelchairaccessibleamenity','cocktailseatingseatingoption', 'classroomseatingoption','ushapeseatingoption','sixtyroundseatingoption','boardroomseatingoption','theaterseatingoption','hallowsquareseatingoption','roomimage_set')

Related

Django rest framework get data from foreign key relation?

I have a models like this:
class Author(models.Model):
name = models.CharField(max_length=150, blank=False, null=False)
dob = models.DateField(null=True, blank=True)
description = models.TextField(max_length=2000, blank=False, default="This author doesn't have any description yet!")
image = models.ImageField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200, blank=False, null=False)
author = models.CharField(max_length=200)
genres = models.ManyToManyField(Genre, related_name='genre', blank=True)
author = models.ForeignKey(Author, related_name='author', blank=True, on_delete=models.CASCADE)
description = models.TextField(max_length=1200, blank=False, default="This book doesn't have description yet!")
image = models.ImageField(default="")
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.title
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
title = models.CharField(max_length=100, null=False, blank=False, help_text="Title overall of your review")
rating = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)], help_text='Rating in range 0-5')
description = models.TextField(max_length=1000, null=False, blank=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
I want to get Book data response in json with my reviews of the book from my Review table but don't know how. I am not getting any useful solution from documentation and Google, please help.
You could set the related_name field in the book field of the Review model.
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name = 'reviews')
...
Then in the serializer, you can add the related field.
class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
reviews = ReviewSerializer(many = True)
class Meta:
model = Book
fields = '__all__'
extra_fields = ('reviews', )

How to add ArrayField in Django?

my models.py
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_registered = models.IntegerField(default=0)
# registered_students = models.ManyToManyField(RegisteredNames, null=True, blank=True)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass_id = models.ForeignKey
I am creating a endpoint where when a user register himself his name will get added to registered_students , so i had made a registered students ManyToMany Field hoping it will get updated when a user is registered but then i understand that it will contain all the names that are present in the RegisteredNames Model meaning names registered across all the liveclasses but i want only the names that are registered for a particular liveclass in the field so i need a array like field which i think is not possible so please help me in improving my logic, how can i achieve it
The documentation and django tutorials are very good: https://docs.djangoproject.com/en/3.2/topics/db/models/ https://docs.djangoproject.com/en/3.2/intro/tutorial02/#creating-models
Your code is very close. You don’t need the many-to-many field, and you need to specify the type of the Foreign key relationship in the RegisteredNames. You can do this:
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass = models.ForeignKey(LiveClass_details, on_delete=Models.CASCADE)
Then, simply:
name = RegisteredNames.objects.create(name="Dhruv", liveclass_id=1)
To get all the registered names from a liveclass_details:
names = LiveClass_details.objects.get(id=1).registerednames_set.all()
num_reg = len(names)

IntegrityError at /job/create/ NOT NULL constraint failed: core_job.category_id

I'm creaating an api that user can create a job. when I want to test it with postman and create a job I have this error:
IntegrityError at /job/create/
NOT NULL constraint failed: core_job.category_id
how do i can fix it ?? I'm using generic CreateAPIView
models:
class Category(models.Model):
name = models.CharField(max_length=300)
slug = models.SlugField(max_length=300, unique=True, help_text='write in English.')
sub_category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.CASCADE)
class Job(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=400, unique=True)
slug = models.SlugField(max_length=400, unique=True, allow_unicode=True)
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING)
image_1 = models.ImageField(upload_to='products_pic/%Y/%m/%d/', null=True, blank=True)
description = models.TextField(null=True, blank=True)
phone1 = models.CharField(max_length=12, null=True, blank=True)
phone2 = models.CharField(max_length=12, null=True, blank=True)
phase = models.CharField(max_length=1, null=True, blank=True)
address = models.TextField(null=True, blank=True)
daily_start_work_time = models.TimeField(null=True, blank=True)
daily_end_work_time = models.TimeField(null=True, blank=True)
create_date = models.DateTimeField(auto_now_add=True)
update_date = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
popular = models.BooleanField(default=False)
views:
class JobCreateView(generics.CreateAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = JobSerializer
queryset = Job.objects.all()
serializers:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class JobSerializer(serializers.ModelSerializer):
category = serializers.SerializerMethodField()
class Meta:
model = Job
fields = '__all__'
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
def get_category(self, obj):
return obj.category.name
The category field is not populating with any value when you create the job. I mean category field is Null when you save that form. I am not sure but any way the problem is related to category field

How to filter django rest framework serializers's drowp down items?

I want to assign Tasks to only the staffs. Therefore, I want my dorpdown list should only show the users that have a role of is_staff = True.
But my drop down list now shows all the users (Superuser, Authority, General_user) that are available in the database.
How to modify this to only show staffs in the drop down list which should only show two users since I've assigned two users with staff role...?
My Model Classes:
Custom-User Model:
class User(AbstractBaseUser, PermissionsMixin):
"""
Responsible for handleing App user's data
"""
email = models.EmailField(max_length=255, unique=True)
nid = models.CharField(max_length=30, unique=True)
username = models.CharField(max_length=20, blank=True, null=True)
date_of_birth = models.DateTimeField(blank=True, null=True)
first_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
image = models.FileField(
upload_to=FileManager.photo_path, null=True, blank=True)
is_active = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_authority = models.BooleanField(default=False)
is_specialist = models.BooleanField(default=False)
is_general_user = models.BooleanField(default=False)
timestamps = models.DateTimeField(auto_now_add=True)
update = models.DateTimeField(auto_now=True)
objects = user_manager.UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['nid']
Tasks Model
class Task(BaseAbstractModel):
'''
Responsible for Storing and Providing Tasks data
'''
assignment = models.ForeignKey(Assignment,
on_delete=models.DO_NOTHING,
related_name='+')
assigne_to = models.ForeignKey(User,
on_delete=models.DO_NOTHING,
related_name='+')
task_name = models.CharField(max_length=300)
is_done = models.BooleanField(default=False)
created_by = models.ForeignKey(User,
on_delete=models.DO_NOTHING,
related_name='created_by')
Serializer:
class TaskListSerializer(serializers.ModelSerializer):
'''
Will be serializing Task's data
'''
created_by = UserListSerializer(read_only=True)
class Meta:
model = Task
fields = ('assignment',
'assigne_to',
'task_name',
'is_done',
'created_by',)
Generic Create View
class CreateTaskView(generics.CreateAPIView):
queryset = Task.objects.all()
serializer_class = TaskListSerializer
Try to use PrimaryKeyRelatedField with queryset argument:
class TaskListSerializer(serializers.ModelSerializer):
'''
Will be serializing Task's data
'''
created_by = UserListSerializer(read_only=True)
assigne_to = serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(is_staff=True))
class Meta:
model = Task
fields = ('assignment',
'assigne_to',
'task_name',
'is_done',
'created_by',)

DRF need values instead of ID

This is my serializer class
class ProjectSerializer(ModelSerializer):
class Meta:
model = Project
exclude = ['deleted_at']
This is Models.py
class MandatoryFields(SoftDeletionModel):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="%(app_label)s_%(class)s_created",null=True)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="%(app_label)s_%(class)s_updated",null=True)
created_date = models.DateTimeField(auto_now_add=True,null=True)
modified_date = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Project(MandatoryFields, Model):
project_name = models.CharField(max_length=255, blank=True)
project_areas = models.CharField(max_length=255, blank=True)
project_manager = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True,
related_name="%(app_label)s_%(class)s_project_manager")
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
REQUIRED_FIELDS = []
def __str__(self):
return self.project_name
I am getting Id's for the foreign keys created_by,updated_by,project_manager .But I need the values instead of Id.
for example I am getting
created_by : 1
But I need
created_by: Alex
I have tried the following
class ProjectSerializer(ModelSerializer):
created_by = SlugRelatedField(read_only=True, slug_field='created_by')
class Meta:
model = Project
exclude = ['deleted_at']
But I am getting null values.
I think that's achievable by specifying source attribute for serializer field
Somthing like this:
class ProjectSerializer(ModelSerializer):
created_by = CharField(source="created_by.first_name")
class Meta:
model = Project
exclude = ['deleted_at']
Reference : https://www.django-rest-framework.org/api-guide/fields/#source