I have a simple model and a serializer which uses additional keyword arguments(extra_kwargs) to limit max and min value for a field. I want to write two test cases in my tests.py to both test valid and invalid values for that field (weight). How should I do this?
I am using Python 2.7.
Model
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=100)
weight = models.FloatField()
Serializer
from rest_framework import serializers
from .models import Person
class PersonSerializer(serializers.ModelSerializer):
model = Person
fields = ('name', 'weight')
extra_kwargs = {'weight': {'min_value': 5, 'max_value': 1000}}
tests.py
from django.test import TestCase
from .models import Person
class ModelTestCase(TestCase):
def setUp(self):
self.person = Person(name='Sam', weight=150)
def test_when_weight_isValid(self):
#e.g. when weight = 200
def test_when_weight_notValid(self):
#e.g. when weight = 3
import json
from django.urls import reverse
from django.contrib.auth import authenticate
from rest_framework import status
from rest_framework.test import APITestCase
from .models import *
class UserTests(APITestCase):
def setUp(self):
self.person = Person(name='Sam', weight=150)
def test_when_weight_isvalid(self):
url = reverse('person-detail', kwargs={'pk': self.person.id})
data = {'weight': 200}
response = self.client.patch(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
print json.dumps(response.data, ensure_ascii=False, indent=2)
Something like this,code is untest.
Related
I want to add a new comment with the post method, but it gives an error
{'non_field_errors': [ErrorDetail(string='Invalid data. Expected a dictionary, but got ModelBase.', code='invalid')]}
Serializers :
from rest_framework import serializers
from .models import Products,ProductsComments
class ProdcutsSerializers(serializers.ModelSerializer):
colors = serializers.SlugRelatedField(many=True,read_only=True,slug_field='name')
category = serializers.SlugRelatedField(many=True,read_only=True,slug_field='name')
sizes = serializers.SlugRelatedField(many=True,read_only=True,slug_field='name')
class Meta:
model = Products
fields = '__all__'
class ProductsCommentsSerializers(serializers.ModelSerializer):
user = serializers.SlugRelatedField(many=True,read_only=True,slug_field='id')
product = serializers.SlugRelatedField(many=True,read_only=True,slug_field='id')
class Meta:
model = ProductsComments
fields = '__all__'
Views :
from rest_framework.decorators import api_view,permission_classes
from rest_framework.response import Response
from rest_framework import status
from .serializers import *
from .models import *
#api_view(['GET'])
def products_list(request):
products = Products.objects.all()
data = ProdcutsSerializers(products,many=True).data
return Response(data)
#api_view(['GET'])
def products_comments_list(request):
products_comments = ProductsComments.objects.all()
data = ProductsCommentsSerializers(products_comments,many=True).data
return Response(data)
#api_view(['POST'])
def products_comments_add(request):
data = ProductsCommentsSerializers(data=ProductsComments)
if data.is_valid():
print('Ok')
else:
print('not')
#print(data)
print(data.errors)
return Response({"M": "not"})
I have 2 models named Recipe and Step..
I have serialized both to make an API for GET request.. I want to know is there a way to create for POST request so that I can send both the data (steps and recipe) in the same request?
models.py:
from django.db import models
class Recipe(models.Model):
title = models.CharField( max_length=50)
uuid = models.CharField( max_length=100)
def __str__(self):
return f'{self.uuid}'
class Step(models.Model):
step = models.CharField(max_length=300)
uuid = models.ForeignKey(Recipe, on_delete=models.CASCADE)
def __str__(self):
return f'{self.step} - {self.uuid}'
serializers.py:
from rest_framework import serializers
from .models import *
class RecipeSerializer(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = ['title', 'uuid']
class StepSerializer(serializers.ModelSerializer):
class Meta:
model = Step
fields = ['step', 'uuid']
views.py:
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import *
from .models import *
#api_view(['GET'])
def apiOverview(request):
api_urls = {
'List':'/recipe-list/',
'Detail View':'/recipe-detail/<str:pk>/',
'Create':'/recipe-create/',
'Update':'/recipe-update/<str:pk>/',
'Delete':'/recipe-delete/<str:pk>/',
'Steps' : '/steps/<str:pk>'
}
return Response(api_urls)
#api_view(['GET'])
def recipeList(request):
recipes = Recipe.objects.all()
serializer = RecipeSerializer(recipes, many=True)
return Response(serializer.data)
#api_view(['GET'])
def recipeDetail(request, pk):
recipe = Recipe.objects.get(uuid=pk)
recipe_serializer = RecipeSerializer(recipe, many=False)
steps = Step.objects.filter(uuid=pk)
steps_serializer = StepSerializer(steps, many=True)
return Response({
'recipe' : recipe_serializer.data,
'steps' : steps_serializer.data
})
How can I create a view for POST and handle both the models?
Try:
from rest_framework import generics
from .models import *
class StepAndRecipe(generics.CreateAPIView):
queryset = Step.objects.all()
queryset = Recipe.objects.all()
serializer_class = StepSerializer
serializer_class = RecipeSerializer
Add in urls.py:
from django.urls import path
from .views import StepAndRecipe
urlpatterns = [
path('steprecipepost', StepAndRecipe.as_view(), name='steps_recipes')
This will only work with POST! And one more thing: take care with the raw data and the HTML form, maybe theses get a little confused since you are using two models in the same view.
How can I send a 220,000-line CSV file to Django using the Rest Framework API? Thank you.
#Botta- How about something like this
from django.db import models
Create your models here.
class MyFile(models.Model):
file = models.FileField(blank=False, null=False,upload_to='images/')
description = models.CharField(null=True,max_length=255)
uploaded_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'MyFiles'
class MyFileView(APIView):
# MultiPartParser AND FormParser
# https://www.django-rest-framework.org/api-guide/parsers/#multipartparser
# "You will typically want to use both FormParser and MultiPartParser
# together in order to fully support HTML form data."
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
file_serializer = MyFileSerializer(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializers.py
from rest_framework import serializers
from .models import MyFile
class MyFileSerializer(serializers.ModelSerializer):
class Meta:
model = MyFile
fields = ('file', 'description', 'uploaded_at')
#Stacy Hi. I made the changes, but it didn't work. I would like the fields in the CSV file to go automatically to my models and to the REST API. I would like to import my CSV data when uploading the file. Thanks.
models.py
from django.db import models
class MyFile(models.Model):
file = models.FileField(blank=False, null=False,upload_to='images/')
description = models.CharField(null=True,max_length=255)
uploaded_at = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=150)
sex = models.CharField(max_length=150)
age = models.CharField(max_length=50)
height = models.CharField(max_length=150)
def __str__(self):
return self.description
class Meta:
verbose_name_plural = 'MyFiles'
serializers.py
from rest_framework import serializers
from .models import MyFile
class MyFileSerializer(serializers.ModelSerializer):
class Meta:
model = MyFile
fields = ("file", "description", "uploaded_at", "name", "sex", "age", "height",)
#Stacy- Hello. I was able to upload the csv file and pass it to my API as .CSV, however, I would like all fields in my CSV file to be transferred to API Rest. For example ID, Name, Age and Profile. It's possible? Thank you. Thank you.
serializers.py
from rest_framework import serializers
from .models import MyFile
class MyFileSerializer(serializers.ModelSerializer):
class Meta:
model = MyFile
fields = ('file', 'description', 'uploaded_at')
models.py
from django.db import models
class MyFile(models.Model):
file = models.FileField(blank=False, null=False,upload_to='images/')
description = models.CharField(null=True,max_length=255)
uploaded_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.description
class Meta:
verbose_name_plural = 'MyFiles'
views.py
from rest_framework.parsers import MultiPartParser, FormParser
from .models import MyFile
from .serializers import MyFileSerializer
from rest_framework import generics
from rest_framework import viewsets
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.exceptions import NotFound
from rest_framework.response import Response
from rest_framework.views import APIView
class MyFileViewSet(viewsets.ModelViewSet):
queryset = MyFile.objects.all()
serializer_class = MyFileSerializer
urls.py
from .views import MyFileViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'', MyFileViewSet)
urlpatterns = router.urls
How to count rows on PostgreSQL database in Django and show using highchart?
Example: I want to show how much record/row from 7.00am to 7.00 am next day.
models:
from django.db import models
from datetime import datetime, date
class hujan(models.Model):
id = models.AutoField(primary_key=True)
tanggal = models.DateTimeField(auto_now_add=True)
dtinms = models.IntegerField()
hujan = models.FloatField()
serializers:
from rest_framework import serializers
from .models import hujan, cahayasuhukelembapan
class hujanSerializer(serializers.ModelSerializer):
class Meta:
model = hujan
fields = ('tanggal','dtinms','hujan')
views:
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, JsonResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import TemplateHTMLRenderer
from .models import hujan
from .serializers import hujanSerializer
def homePageView(request):
return render(request,'homepage.html')
class hujanlistall(APIView):
def get(self, request):
Hujan = hujan.objects.all()
serializer = hujanSerializer(Hujan, many=True)
return JsonResponse(serializer.data,safe=False)
Modify "views.py" file,
import datetime
class hujanlistall(APIView):
def get(self, request):
Hujan = hujan.objects.filter(tanggal__range = (datetime.datetime.combine(start_date,datetime.time.min),datetime.datetime.combine(end_date, datetime.time.max)))
RowCount = len(Hujan)
serializer = hujanSerializer(Hujan, many=True)
return JsonResponse(serializer.data,safe=False)
I'm trying to receive a post from a server in the format:
{
"event_type": "test",
"event_info": {
"key": "value",
"more unknown key":"Value pairs"...
}
}
Then serialize it into a sqlite db.
I'm not finding a good way to do this. It doesn't like {} I get returned "Not a valid string." I haven't found a good way to accept the json object. I could just store the json as a string but I can't figure out how to convert it to a string either.
I have views.py:
from django.shortcuts import render
from .models import Subscription
from .Serializers import SubscriptionSerializer
from rest_framework import viewsets
from django.http import HttpResponse
class SubscriptionViewSet(viewsets.ModelViewSet):
queryset = Subscription.objects.all().order_by('-date_created')
serializer_class = SubscriptionSerializer
http_method_names = ['get', 'post', 'delete']
models.py
from __future__ import unicode_literals
from django.db import models
class Subscription(models.Model):
event_type = models.TextField(default='Failed to set')
event_info = models.TextField(default='Failed to set')
date_created = models.DateTimeField(auto_now=True)
Serializers.py
from rest_framework import serializers
from .models import Subscription
class SubscriptionSerializer(serializers.ModelSerializer):
class Meta:
model = Subscription
fields = ('id', 'event_type', 'event_info')
Try using nested serializer:
class KeySerializer(serializers.Serializer):
key = serializers.CharField(max_length=30)
class EventSerializer(serializers.Serializer):
event_type = serializers.CharField(max_length=30)
event_info = KeySerializer()
EventSerializer should be able to parse/validate json you posted.