I would like to create a route that returns some model properties as a JSON with the Django REST framework and filter them based on some properties. But I don't get the serializer to working properly.
class MaxQuantPathSerializer(serializers.ModelSerializer):
class Meta():
model = MaxQuantRun
fields = '__all__'
depth=0
class MaxQuantPathsAPI(generics.ListAPIView):
filter_fields = ['project', 'setup']
filter_backends = [DjangoFilterBackend]
def get(self, request, format=None):
get_data = request.query_params
queryset = MaxQuantRun.objects.filter(project=get_data['project'])
serializer = MaxQuantPathSerializer(queryset, many=True)
data = serializer.data
return JsonResponse(data, status=201, safe=False)
The queryset returns some values but the serializer returns an empty dictionary.
I updated the code based on the comments below. Now, a json file is returned.
Related
I getting null in return when in fact i have data in the database, I don't where the problem lies, pretty frustrated by this, if I am not calling is_valid then it throws an assertion error but anyways data is still empty
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
View
#api_view(['GET'])
def get_data(request):
product_data = Product.objects.all()
print(product_data)
serialized_data = ProductSerializer(data = product_data, many =True)
data = {}
if serialized_data.is_valid():
data['status']='valid'
else:
data['status']='not valid'
return Response(data)
You were using the DRF serializer in the wrong way, try to use the instance argument, instead of data while serializing the data.
#api_view(['GET'])
def get_data(request):
product_qs = Product.objects.all()
serializer = ProductSerializer(instance=product_qs, many=True)
return Response(serializer.data)
i want to join two tables using django select_related. But how can i serialize those data from two tables to get serialized details including full image url from another table
My View.py
class getALlUserProfileDataAPIView(views.APIView):
permission_classes = (permissions.AllowAny,)
def get(self, request):
#usedraa = User.objects.filter(qs).select_related('userAddress').values('id','useraddress__country', 'useraddress__state', 'useraddress__city','email','username','first_name','last_name','password')
usedraa = User.objects.filter().select_related('Profile').values('username','profile__image','first_name','last_name')
#usedraa = User.objects.all().prefetch_related()
userProfileSerializer0 = userProfileSerializer(usedraa, context={'request': request}, many=True)
return Response(userProfileSerializer0.data, status=status.HTTP_201_CREATED)
Serailizer
ass userProfileSerializer(serializers.ModelSerializer):
prodata = serializers.HyperlinkedIdentityField(read_only=True, view_name = 'profile')
# prodata = ProfileSerializer(read_only=True, many=True) # many=True is required
class Meta:
model = User
fields = ("first_name","last_name","username","prodata")
I am learning DRF now, im little puzzuled by this many = True code. What does it do? Or what does it mean?
example 1
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.RelatedField(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
example 2
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)
def list(self, request):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
I think you are confusing many=True with many to many realtionship, but the concepts is not like that
by setting many=True you tell drf that queryset contains mutiple items (a list of items) so drf needs to serialize each item with serializer class (and serializer.data will be a list)
if you don't set this argument it means queryset is a single instance and serializer.data will be a single object)
I am working on project using django rest framework in which i have to filter different parameters given by user.I am using django Filter backend.
Here is my code:
class FilterViewSet(viewsets.ModelViewSet):
serializer_class = SearchSerializer
#Filters on specific fields
filter_backends = (DjangoFilterBackend,)
filter_fields = ('property_zipcode','property_state',
'property_county',
'property_city','property_area',)#range between 100 to 500 or area less then 500.
#range is pass by user as a property_area=300.
def filter_queryset(self, queryset):
if self.request.query_params.get('property_state', None):
queryset = super(FilterViewSet, self).filter_queryset(self.get_queryset())
return queryset
else:
queryset = self.get_queryset()
return queryset
Everything is working fine. But now i have to filter property_area based on range like 100 sqft to 500 sqft. How i can achieve this using djangoFilter backend?
Thanks #Gabriel Muj. From the django-filter documentation i solved my problem. I created my own filter class added fields which is use for filters.
class Filter(django_filters.FilterSet):
class Meta:
model = Property
fields = {
'property_state': ['exact'],
'year_built': ['lt', 'gt'],
'tax':['lt','gt'],
}
Call it in Viewset:
class FilterViewSet(viewsets.ModelViewSet):
serializer_class = SearchSerializer
#Filters on specific fields
filter_class = Filter
def filter_queryset(self, queryset):
if self.request.query_params.get('property_state', None):
queryset = super(FilterViewSet, self).filter_queryset(self.get_queryset())
return queryset
else:
queryset = self.get_queryset()
return queryset
In Django REST Framework API, list of database table records are not getting updated until the API restart or any code change in python files like model, serializer or view. I've tried the transaction commit but it didn't worked. Below is my view :
class ServiceViewSet(viewsets.ModelViewSet):
#authentication_classes = APIAuthentication,
queryset = Service.objects.all()
serializer_class = ServiceSerializer
def get_queryset(self):
queryset = self.queryset
parent_id = self.request.QUERY_PARAMS.get('parent_id', None)
if parent_id is not None:
queryset = queryset.filter(parent_id=parent_id)
return queryset
# Make Service readable only
def update(self, request, *args, **kwargs):
return Response(status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, *args, **kwargs):
return Response(status=status.HTTP_400_BAD_REQUEST)
Serializer looks like this :
class ServiceSerializer(serializers.ModelSerializer):
class Meta:
model = Service
fields = ('id', 'category_name', 'parent_id')
read_only_fields = ('category_name', 'parent_id')
and model looks like this :
class Service(models.Model):
class Meta:
db_table = 'service_category'
app_label = 'api'
category_name = models.CharField(max_length=100)
parent_id = models.IntegerField(default=0)
def __unicode__(self):
return '{"id":%d,"category_name":"%s"}' %(self.id,self.category_name)
This problem is occuring only with this service, rest of the APIs working perfectly fine. Any help will be appreciated.
Because you are setting up the queryset on self.queryset, which is a class attribute, it is being cached. This is why you are not getting an updated queryset for each request, and it's also why Django REST Framework calls .all() on querysets in the default get_queryset. By calling .all() on the queryset, it will no longer use the cached results and will force a new evaluation, which is what you are looking for.
class ServiceViewSet(viewsets.ModelViewSet):
queryset = Service.objects.all()
def get_queryset(self):
queryset = self.queryset.all()
parent_id = self.request.QUERY_PARAMS.get('parent_id', None)
if parent_id is not None:
queryset = queryset.filter(parent_id=parent_id)
return queryset