Serializer data is not showing on the API - django
Hey Guys this is my first project in Django, I am trying to get my 'foreign keys' field into my API with Django Rest framework.
I am trying to do a Post a product. since i cannot see input fields i am stuck here.
It might be something very simpel, i might didn’t see it.
*******UPDATE********
As requested, have put an image here for more details of what i actually want to achieve.
In the image below is what i WANT in my api to show and i do get it like this, all my field like how i want them (apart from that i get category twice , one in digits also)
But if u take a closer look down below, the POST form is limited to the attributes of the product Model class itself. So i can not do an actual post from the frontend side.
in the serializers
If i comment the fields out i do get down below my fields to POST, yeah.. but When i post i get digits in my API rather than the names of the foreign keys
So notice i get all the field that i need for my frontend in order to handle the post function. But then i get digits in the api instead
I hope i made it more clear than before.. :)
Thank you in advance
serializers.py
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from .models import *
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password')
extra_kwargs = {'password':{'write_only':True,'required':True}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
print(user)
Token.objects.create(user=user)
return user
class ProductSerializer(serializers.ModelSerializer):
product_id = serializers.CharField(source='product.url', read_only=True)
category_name = serializers.CharField(source='category.name', read_only=True)
user_id = serializers.CharField(source='user.id', read_only=True)
subject = serializers.CharField(source='subject.subject', read_only=True)
condition = serializers.CharField(source='condition.condition', read_only=True)
major = serializers.CharField(source='major.major', read_only=True)
state = serializers.CharField(source='state.state', read_only=True)
school = serializers.CharField(source='school.school', read_only=True)
location = serializers.CharField(source='location.location', read_only=True)
class Meta:
model = Product
fields = '__all__'
class SubjectSerializer(serializers.ModelSerializer):
model = Subject
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('url', 'id', 'name')
class StateSerializer(serializers.ModelSerializer):
# state_count = serializers.SerializerMethodField()
class Meta:
model = State
fields = ['id', 'url', 'state']
# def get_state_count(self, obj):
# if State.objects.count()
# return obj.children().count()
# return 0
class ConditionSerializer(serializers.ModelSerializer):
class Meta:
model = Condition
fields = '__all__'
class MajorSerializer(serializers.ModelSerializer):
class Meta:
model = Major
fields = '__all__'
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = '__all__'
class FaqSerializer(serializers.ModelSerializer):
class Meta:
model = Faq
fields = '__all__'
views
from django.shortcuts import render
from rest_framework import viewsets, status
from rest_framework.decorators import api_view
from .models import Product, State, Category, Subject
from django.contrib.auth.models import User
from .serializer import *
from rest_framework.permissions import IsAuthenticated,AllowAny
from rest_framework.authentication import TokenAuthentication
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.response import Response
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.pagination import LimitOffsetPagination
class ProductViewPagination(LimitOffsetPagination):
default_limit = 8
max_limit = 12
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
product_count = Product.objects.count()
authentication_classes = (TokenAuthentication,)
permission_calsses = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
search_fields = ('=title','=category__name','=user__id','=subject__subject', '=major__major', '=condition__condition', '=location__location')
pagination_class = ProductViewPagination
# def delete(self,request,*args,**kwargs):
# response = {'message':'product cannot be updated like this'}
# return Response(response, status = statu.HTTP_400_BAD_REQUEST)
# def create(self,request,*args,**kwargs):
# response = {'message':'product cannot be created like this'}
# return Response(response, status = status.HTTP_400_BAD_REQUEST)
class CategoryViewSet(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
permission_calsses = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
search_fields = ('=name', 'id')
class SubjectViewSet(viewsets.ModelViewSet):
queryset = Subject.objects.all()
serializer_class = SubjectSerializer
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
search_fields = ('=subject',)
class ConditionViewSet(viewsets.ModelViewSet):
queryset = Condition.objects.all()
serializer_class = ConditionSerializer
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
search_fields = ('=condition',)
class MajorViewSet(viewsets.ModelViewSet):
queryset = Major.objects.all()
serializer_class = MajorSerializer
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
search_fields = ('=major',)
class LocationViewSet(viewsets.ModelViewSet):
queryset = Location.objects.all()
serializer_class = LocationSerializer
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
search_fields = ('=location',)
# class StateCountViewSet(viewsets.ModelViewSet):
# queryset = State.objects.all()
# serializer_class = StateSerializer
# permission_calsses = (IsAuthenticated,)
# def get(self, request, format=None):
# state_count = State.objects.count()
# content = {'state_count' : state_count}
# return Response(content)
class StateViewSet(viewsets.ModelViewSet):
queryset = State.objects.all()
serializer_class = StateSerializer
permission_calsses = (IsAuthenticated,)
class FaqViewSet(viewsets.ModelViewSet):
queryset = Faq.objects.all()
serializer_class = FaqSerializer
permission_calsses = (AllowAny,)
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (AllowAny, )
# #api_view(['POST',])
# def registration_view(request):
# if request.method == 'POST':
# serializer = RegristrationSerializer(data=request.data)
# data = {}
# if serializer.is_valid():
# user = serialzer.save()
# data['response'] = "successfully registered a new userrrR"
# data['username'] = user.username
# else:
# data = serializer.errors
# return user
urls.py
from django.conf.urls import url, include
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
from django.urls import path
from restapi.views import *
# class UserSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = User
# fields = ['id', 'url', 'username', 'email', 'is_staff']
# # ViewSets define the view behavior.
# class UserViewSet(viewsets.ModelViewSet):
# queryset = User.objects.all()
# serializer_class = UserSerializer
# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('product', ProductViewSet)
router.register('category', CategoryViewSet)
router.register('state', StateViewSet)
#router.register('stateCount', StateCountViewSet)
router.register('subject', SubjectViewSet)
router.register('major', MajorViewSet)
router.register('condition', ConditionViewSet)
router.register('location', LocationViewSet)
router.register('faq', FaqViewSet)
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
#path('state/count/:state_id', StateCountViewSet, name='states-count')
]
admin.py
from django.contrib import admin
from .models import *
admin.site.register(Product)
admin.site.register(Category)
admin.site.register(Subject)
admin.site.register(State)
admin.site.register(Major)
admin.site.register(Condition)
admin.site.register(Location)
admin.site.register(Faq)
model.py
from django.db import models
from django.contrib.auth.models import User
# class User(models.Model):
# id_user = models.DecimalField(max_digits=10, decimal_places=2, null=True)
# def __str__(self):
# return self.id_user
class Faq(models.Model):
question = models.CharField(max_length = 400, null = True,)
answer = models.CharField(max_length = 900, null = True,)
def __str__(self):
return self.question
class Category(models.Model):
name = models.CharField(max_length = 200, null = True,)
def __str__(self):
return self.name
class State(models.Model):
STATE_CHOICES = [('Ordered', 'Ordered'), ('Pending', 'Pending'),
('Placed', 'Placed')
]
state = models.CharField(max_length = 200, null = True,
choices = STATE_CHOICES)
def __str__(self):
return self.state
class Subject(models.Model):
SUBJECT_CHOICES=[('Mathematics','Mathematics'),('Algoritmes','Algoritmes'),('Analyses','Analyses'),('Informatica','Informatica'),]
subject=models.CharField(max_length=200,null=True,choices=SUBJECT_CHOICES)
def __str__(self):return self.subject
class Major(models.Model):
MAJOR_CHOICES = (
('IT','IT'),
('Marketing','Marketing'),
('DIFF','DIFF'),
)
major = models.CharField(max_length=200,choices=MAJOR_CHOICES, null=True)
def __str__(self):return self.major
class Condition(models.Model):
CONDITION_CHOICES = [
('New','New'),
('Used','Used'),
]
condition = models.CharField(max_length=200,choices=CONDITION_CHOICES, null=True)
def __str__(self):return self.condition
class Location(models.Model):
LOCATION_CHOICES = [
('Brussel','Brussel'),
('Leuven','Leuven'),
('Gent','Gent'),
('Antwerpen','Antwerpen'),
]
location = models.CharField(max_length=200,choices=LOCATION_CHOICES, null=True)
def __str__(self):return self.location
class Product(models.Model):
user = models.ForeignKey(User,null=True, on_delete=models.SET_NULL)
state = models.ForeignKey(State, null=True, on_delete=models.SET_NULL)
category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
subject = models.ForeignKey(Subject, null=True, on_delete=models.SET_NULL)
major = models.ForeignKey(Major, null=True, on_delete=models.SET_NULL)
condition = models.ForeignKey(Condition, null=True, on_delete=models.SET_NULL)
location = models.ForeignKey(Location, null=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=200)
description = models.TextField(max_length=800, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2, null=True)
#image = models.ImageField(upload_to='post_image', blank=True, width_field=None, height_field=None, max_length=100,)
date_created = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
unique_together = (('user','title'),)
index_together = (('user','title'),)
SCHOOL_CHOICES = (
('Erasmushogeschool | EHB',(
('Campus Kaai', 'Campus Kaai'),
('Campus Bloemberg', 'Campus Bloemberg'),
)),
('Vrije Universiteit Brussel | VUB',(
('Campus Jette', 'Campus Jette'),
('Campus Schaarbeek', 'Campus Schaarbeek'),
)),
('Katholieke universiteit leuven | KUL',(
('KUL Gent', 'KUL Gent'),
('Campus Antwerpen', 'Campus Antwerpen'),
)),
)
school = models.CharField(max_length=50, choices=SCHOOL_CHOICES, null=True)
# MAJOR_CHOICES = (
# ('IT','IT'),
# ('Marketing','Marketing'),
# ('DIFF','DIFF'),
# )
# major = models.CharField(max_length=200,choices=MAJOR_CHOICES, null=True)
# SUBJECT_CHOICES = [
# ('Mathematics','Mathematics'),
# ('Algoritmes','Algoritmes'),
# ('Analyses','Analyses'),
# ]
# subject = models.CharField(max_length=200,choices=SUBJECT_CHOICES, null=True)
# CONDITION_CHOICES = [
# ('New','New'),
# ('Used','Used'),
# ]
# condition = models.CharField(max_length=200,choices=CONDITION_CHOICES, null=True)
# LOCATION_CHOICES = [
# ('Brussel','Brussel'),
# ('Leuven','Leuven'),
# ('Gent','Gent'),
# ('Antwerpen','Antwerpen'),
# ]
# location = models.CharField(max_length=200,choices=LOCATION_CHOICES, null=True)
def __str__(self):
return self.title
Related
Filter current user products using queryset in DRF returns []
I am trying to filter list of products linked with a user. I want to display only current users product instead of listing all. I tried this class ProductCreateList(generics.ListCreateAPIView): serializer_class = ProductSerializer def get_queryset(self): user = self.request.user return Product.objects.filter(user=user.id) serializers.py class ProductSerializer(serializers.ModelSerializer): class Meta: model = Product fields = ['id', 'user', 'name', 'imgUrl', 'selling_price', 'actual_price', 'quantity', 'get_profit'] models.py class Product(models.Model): user = models.ForeignKey('accounts.Account', on_delete=models.CASCADE, default=1) name = models.CharField(max_length=100, null=True, blank=True) imgUrl = models.TextField(default='') selling_price = models.FloatField(null=True, blank=True) actual_price = models.FloatField(null=True, blank=True) quantity = models.IntegerField() I got [] object when I tried to execute the endpoint. What's my mistake here?
There are a few mistakes, mainly in your view. I have done the following: models.py from django.db import models from django.contrib.auth import get_user_model class Product(models.Model): user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, default=1) name = models.CharField(max_length=100, null=True, blank=True) imgUrl = models.TextField(default='') selling_price = models.FloatField(null=True, blank=True) actual_price = models.FloatField(null=True, blank=True) quantity = models.IntegerField() class Meta: db_table = 'product' serializers.py: Remove 'get_profit' field or implement a serializermethodfield from rest_framework import serializers from core.models import Product class ProductSerializer(serializers.ModelSerializer): class Meta: model = Product fields = ['id', 'user', 'name', 'imgUrl', 'selling_price', 'actual_price', 'quantity'] views.py: To filter by user, guarantee that the user is Authenticated and has auth permission by using authentication_classes and permission_classes. Use the filter_queryset hook, to filter your queryset by user. from rest_framework.authentication import SessionAuthentication, BasicAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework import generics from core.api.serializers import ProductSerializer from core.models import Product class ProductCreateList(generics.ListCreateAPIView): authentication_classes = [SessionAuthentication, BasicAuthentication] permission_classes = [IsAuthenticated] serializer_class = ProductSerializer queryset = Product.objects.all() def filter_queryset(self, queryset): queryset = queryset.filter(user=self.request.user) return super().filter_queryset(queryset)
Django_filter on an apiview
I have been trying to use the Django_filter on an APIView, but it just does not work. I am trying to implement a filter search, on some fields on a model. below is how the model is set up class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField(max_length=254, unique=True) name = models.CharField(max_length=250) picture = models.TextField(null=True, blank=True) 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) slug = models.SlugField(max_length=255, unique=True, blank=True) class Skill(models.Model): name = models.CharField(max_length=60) subcategory = models.CharField(max_length=60, blank=True, null=True) created_on = models.DateTimeField(auto_now=True) updated_on = models.DateTimeField(auto_now_add=True) updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.DO_NOTHING) the views.py set up is also as shown below from django_filters import rest_framework as filters class UserFilter(filters.FilterSet): email = filters.CharFilter(lookup_expr='icontains') name = filters.CharFilter(lookup_expr='icontains') profiles__skills = filters.CharFilter(lookup_expr='icontains') class Meta: model = User fields = ('email', 'name', 'profiles__skills') class ListUsersView(APIView, MyPaginationMixin): ''' Gets all the users in the database ''' queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [AllowAny] pagination_class = api_settings.DEFAULT_PAGINATION_CLASS filterset_class = UserFilter def get(self, request): page = self.paginate_queryset(self.queryset) if page is not None: serializer_context = {"request": request} serializer = self.serializer_class(page, context=serializer_context, many=True) return self.get_paginated_response(serializer.data) and finally my serializer.py class UserSerializer(serializers.ModelSerializer): slug = serializers.SlugField(read_only=True) class Meta: model = User fields = ('email', 'name', 'slug', 'picture') read_only_fields = ('email', 'name', 'slug',) my urls.py path('users/', qv.ListUsersView.as_view(), name='list-users'), this is how my result looks like please, how can I get the Django filter to work on the APIView
It seems you are trying to get the similar or exact behavior of DRF ListAPIView by using APIView. I would suggest using ListAPIView over APIView in your case. from rest_framework import generics from django_filters import rest_framework as filters class ListUsersView(generics.ListAPIView): ''' Gets all the users in the database ''' queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [AllowAny] filterset_class = UserFilter filter_backends = (filters.backends.DjangoFilterBackend,) To add filtering capability in APIView, class MyAPIViewKlass(APIView): filter_backends = (filters.DjangoFilterBackend,) def filter_queryset(self, queryset): for backend in list(self.filter_backends): queryset = backend().filter_queryset(self.request, queryset, self) return queryset def get(self, request, *args, **kwargs): base_qs = MyModel.objects.all() filtered_qs = self.filter_queryset(base_qs) serializer = MySerializer(filtered_qs, many=True) return Response(serializer.data)
Why my slug related field shows users object(1) instead of suggested field name in Django?
I wrote an app named as credentials. models, serializers and views are : models.py : from django.db import models class Users(models.Model): username = models.CharField(max_length=20, blank=False) inserted_timestamp = models.DateTimeField(auto_now_add=True) class Meta: ordering = ('inserted_timestamp',) class UsersDetails(models.Model): user = models.ForeignKey( Users, related_name='id_user_details', on_delete=models.DO_NOTHING, ) user_title = models.CharField(max_length=30, blank=True) user_first_name = models.CharField(max_length=25, blank=True) user_last_name = models.CharField(max_length=40, blank=True) user_birthdate = models.DateField(blank=False) inserted_timestamp = models.DateTimeField(auto_now_add=True) details_creator = models.ForeignKey( Users, related_name='dtlcreator_user_details', on_delete=models.DO_NOTHING, # default=1 ) class Meta: ordering = ('user_id',) class UsersPasswords(models.Model): user = models.ForeignKey( Users, related_name='id_user_password', on_delete=models.DO_NOTHING) salt = models.CharField(max_length=200, blank=True) pwdhash = models.CharField(max_length=200, blank=True) inserted_timestamp = models.DateTimeField(auto_now_add=True) pwd_creator = models.ForeignKey( Users, related_name='pwdcreator_user_details', on_delete=models.DO_NOTHING) class Meta: ordering = ('user_id',) Here is serializers.py : from rest_framework import serializers from credentials.models import Users from credentials.models import UsersDetails from credentials.models import UsersPasswords class UsersSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Users fields = ( 'url', 'pk', 'username', 'inserted_timestamp', ) class UsersDetailsSerializer(serializers.HyperlinkedModelSerializer): user = serializers.SlugRelatedField( queryset=Users.objects.all(), slug_field='username', ) details_creator = serializers.SlugRelatedField( queryset=Users.objects.all(), slug_field='username', ) class Meta: model = UsersDetails fields = ( 'url', 'pk', 'user', 'user_title', 'user_first_name', 'user_last_name', 'user_birthdate', 'inserted_timestamp', 'details_creator' ) class UsersPasswordsSerializer(serializers.HyperlinkedModelSerializer): user = serializers.SlugRelatedField( queryset=Users.objects.all(), slug_field='username' ) pwd_creator = serializers.SlugRelatedField( queryset=Users.objects.all(), slug_field='username' ) class Meta: model = UsersPasswords fields = ( 'pk', 'user', 'salt', 'pwdhash', 'inserted_timestamp', 'pwd_creator' ) class UsersDetailsPasswordsSerializer(serializers.HyperlinkedModelSerializer): details = UsersDetailsSerializer(many=True, read_only=True) passwords = UsersPasswordsSerializer(many=True, read_only=True) class Meta: model = Users fields = ( 'url', 'pk', 'username', 'inserted_timestamp', 'details', 'passwords', ) views.py : from rest_framework import generics from rest_framework.response import Response from rest_framework.reverse import reverse from credentials.models import Users, UsersDetails, UsersPasswords from credentials.serializers import UsersSerializer, UsersDetailsSerializer, UsersPasswordsSerializer class UserList(generics.ListCreateAPIView): queryset = Users.objects.all() serializer_class = UsersSerializer name = 'users-list' class UserDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Users.objects.all() serializer_class = UsersSerializer name = 'users-detail' class UserDetailsList(generics.ListCreateAPIView): queryset = UsersDetails.objects.all() serializer_class = UsersDetailsSerializer name = 'usersdetails-list' class UserDetailsDetail(generics.RetrieveUpdateDestroyAPIView): queryset = UsersDetails.objects.all() serializer_class = UsersDetailsSerializer name = 'usersdetails-detail' class UserPasswordsList(generics.ListCreateAPIView): queryset = UsersPasswords.objects.all() serializer_class = UsersPasswordsSerializer name = 'userpasswords-list' class UserPasswordsDetail(generics.RetrieveUpdateDestroyAPIView): queryset = UsersPasswords.objects.all() serializer_class = UsersPasswordsSerializer name = 'userpasswords-detail' class ApiRoot(generics.GenericAPIView): name = 'api-root' def get(self, request, *args, **kwargs): return Response({ 'user-list': reverse(UserList.name, request=request), 'user-details': reverse(UserDetailsList.name, request=request), 'user-passwords': reverse(UserPasswordsList.name, request=request), }) When I intended to add new user details I expect to see username field values but I see users object (1) instread of username, like below picture: What's your idea?
Set __str__ method on Users: class Users(models.Model): ... def __str__(self): return self.username
Django Rest Framework: Serialize multiple images to one post in
I am trying to be able to serialize and upload multiple images to associate with each post. This is my models.py from django.conf import settings from django.db import models from django.db.models.signals import pre_save from .utils import unique_slug_generator class Painting(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, default="", on_delete=models.CASCADE) title = models.CharField(blank=False, null=False, default="", max_length=255) slug = models.SlugField(blank=True, null=True) style = models.CharField(blank=True, null=True, default="", max_length=255) #need to figure out why there is problem when this is False description = models.TextField(blank=True, null=True, default="") size = models.CharField(blank=True, null=True, default="", max_length=255) artist = models.CharField(blank=True, null=True, default="", max_length=255) price = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=20) available = models.BooleanField(default=True) updated = models.DateTimeField(auto_now=True, auto_now_add=False) timestamp = models.DateTimeField(auto_now=False, auto_now_add=True) def __str__(self): return self.title class Meta: ordering = ["-timestamp", "-updated"] class PaintingPhotos(models.Model): title = models.ForeignKey(Painting, default="", on_delete=models.CASCADE) image = models.ImageField(upload_to='uploaded_paintings') def pre_save_painting_receiver(sender, instance, *args, **kwargs): if not instance.slug: instance.slug = unique_slug_generator(instance) pre_save.connect(pre_save_painting_receiver, sender=Painting) my serializers.py from django.contrib.auth import get_user_model, authenticate, login, logout from django.db.models import Q from django.urls import reverse from django.utils import timezone from rest_framework import serializers from .models import Painting, PaintingPhotos User = get_user_model() class UserPublicSerializer(serializers.ModelSerializer): username = serializers.CharField(required=False, allow_blank=True, read_only=True) class Meta: model = User fields = [ 'username', 'first_name', 'last_name', ] # # add PaintingImagesSerializer with the images model here class PaintingPhotosSerializer(serializers.ModelSerializer): class Meta: model = PaintingPhotos fields =[ 'image' ] #becareful here, if anyone submits a POST with an empty title, it will result in the empty slug, (which will mess up the url lookup since the title is the slug in this case) #make title a required field in the actual interface, also remember to don't submit s POST with an empty title from the Django restframework directly class PaintingSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='paintings-api:detail', read_only=True, lookup_field='slug' ) user = UserPublicSerializer(read_only=True) owner = serializers.SerializerMethodField(read_only=True) image = PaintingPhotosSerializer(many=True, read_only=False) class Meta: model = Painting fields = [ 'url', 'user', 'title', 'style', 'description', 'size', 'artist', 'price', 'available', 'updated', 'timestamp', 'owner', 'slug', 'image', ] def get_owner(self, obj): request = self.context['request'] if request.user.is_authenticated: if obj.user == request.user: return True return False my views.py from rest_framework.views import APIView from rest_framework.parsers import MultiPartParser, FormParser from rest_framework.response import Response from rest_framework import generics, permissions, pagination, status from .models import Painting from .permissions import IsOwnerOrReadOnly from .serializers import PaintingSerializer class PaintingPageNumberPagination(pagination.PageNumberPagination): page_size = 5 page_size_query_param = 'size' max_page_size = 20 def get_paginated_response(self, data): author = False user = self.request.user if user.is_authenticated: author = True context = { 'next': self.get_next_link(), 'previous': self.get_previous_link(), 'count': self.page.paginator.count, 'author': author, 'results': data, } return Response(context) class PaintingDetailAPIView(generics.RetrieveUpdateDestroyAPIView): queryset = Painting.objects.all() serializer_class = PaintingSerializer lookup_field = 'slug' permission_classes = [IsOwnerOrReadOnly] class PaintingListCreateAPIView(generics.ListCreateAPIView): queryset = Painting.objects.all() serializer_class = PaintingSerializer permission_classes = [permissions.IsAuthenticatedOrReadOnly] pagination_class = PaintingPageNumberPagination def perform_create(self, serializer): serializer.save(user=self.request.user) I am getting this error: AttributeError: Got AttributeError when attempting to get a value for field image on serializer PaintingSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Painting instance. Original exception text was: 'Painting' object has no attribute 'image'. I am also not sure if I should create another app just to handle all the images. Thanks so much in advance!
Your code looks similar enough to the docs here: https://www.django-rest-framework.org/api-guide/relations/#nested-relationships I can't see what exactly is wrong, but it could be that you haven't created a PaintingPhotos object so there is no model to serialize it. I mentioned in a comment that you can create this through the Django admin.
Hey guys I ended up finding the answer. This stackoverflow answer explains it really well: Multiple images per Model where I messed up was not adding the related_name argument to my photo in my PaintingPhotos model.
expand search and return all objects Django REST Framework
Currently in my ModelViewSet I'm returning all contacts for today, additionally I'm checking if the query_params on the request for searching/filtering is available and not empty, In that case I'm not adding "today" to the queryset so that will perform search on the entire queryset. Problem is that I need to extend search so the user can see other users contacts, but only when he search for them, default view should not be changing if you are not searching, so how can I extend my current filter and return all objects in search. My current view: from rest_framework import viewsets, permissions, filters from cms.restapi.pagination import StandardResultsOffsetPagination from cms_sales.models import LeadContact from cms_sales.restapi.permissions.lead_contact_permissions import LeadContactPermissions from cms_sales.restapi.serializers.lead_contact_serializer import LeadContactSerializer class LeadContactViewSet(viewsets.ModelViewSet): def get_queryset(self): queryset = LeadContact.objects.none() user = self.request.user if user.has_perm('cms_sales.can_view_full_lead_contact_list'): queryset = LeadContact.objects.all() elif user.has_perm('cms_sales.can_view_lead_contact'): queryset = LeadContact.objects.filter(account_handler=user) filter_date = self.request.query_params.get('filter_date', None) search_params = self.request.query_params.get('search', None) if filter_date is not None and (search_params is None or len(search_params) == 0): queryset = queryset.filter(next_action_date=filter_date) return queryset serializer_class = LeadContactSerializer filter_backends = (filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) filter_fields = ('account_handler',) ordering_fields = ( 'first_name', 'last_name', 'account_handler__first_name', 'account_handler__last_name', 'sub_organization_name', 'organization_name', 'next_action_date', 'serial_number', 'status_text') search_fields = ( 'first_name', 'last_name', 'account_handler__first_name', 'account_handler__last_name', 'sub_organization_name', 'organization_name', 'next_action_date', 'serial_number', 'status_text') pagination_class = StandardResultsOffsetPagination permission_classes = [permissions.IsAuthenticated, LeadContactPermissions] Current Serializer: from django.conf import settings from django.contrib.auth.models import User from rest_framework import serializers from cms_sales.models import LeadContact class AccountHandlerSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ('username', 'first_name', 'last_name') class LeadContactSerializer(serializers.ModelSerializer): account_handler = AccountHandlerSerializer() next_action_date = serializers.DateTimeField(format=settings.CUSTOM_DATE_FORMAT_NO_TIME) absolute_url = serializers.URLField(source='get_absolute_url') class Meta: model = LeadContact fields = ( 'pk', 'organization_name', 'sub_organization_name', 'serial_number', 'account_handler', 'status_text', 'first_name', 'last_name', 'next_action_date', 'absolute_url', 'status_display_class' ) depth = 1 Current Model: class LeadContact(models.Model): organization_name = models.CharField(max_length=200, blank=False, null=True) sub_organization_name = models.CharField(max_length=200, blank=False, null=True) serial_number = models.CharField(max_length=30, db_index=True, blank=True, null=True) account_handler = models.ForeignKey(User, blank=True, null=True, related_name='handling_leads', on_delete=models.SET_NULL) next_action_date = models.DateField(null=True, verbose_name="Next action on lead") status_text = models.CharField(max_length=20, default='', blank=True) first_name = models.CharField(_('first name'), max_length=30) last_name = models.CharField(_('last name'), max_length=30)
move the code to check permissions below the code where you check for search param so that you are applying the user filter after checking for search_params def get_queryset(self): queryset = LeadContact.objects.all() if (not user.has_perm('cms_sales.can_view_full_lead_contact_list') and not user.has_parm('cms_sales.can_view_lead_contact')): return queryset.none() user = self.request.user filter_date = self.request.query_params.get('filter_date', None) search_params = self.request.query_params.get('search', None) if filter_date is not None and (search_params is None or len(search_params) == 0): queryset = queryset.filter(next_action_date=filter_date) if user.has_perm('cms_sales.can_view_lead_contact') and not search_params: queryset = queryset.filter(account_handler=user) return queryset