This issue has similar headings to other threads on this forum, but I'm sure this is not a duplicate because one because I didn't overwrite my pagination details or anything (which turned out to be the cause in other questions).
Anyways, Django raised to_representation() must be implemented. I'm completely stuck as there is no relevant documentation regarding this (please comment if you have some) and my case didn't fit in with other people's.
For those of you that think I didn't include everything in the error message, the error message is just this short and ambiguous. View this on github issues
Code:
settings
INSTALLED_APPS = ['rest_framework',]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
view
from rest_framework import viewsets
from .models import Todo
from .serializers import TodoSerializer
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
serializers
from .models import Todo
from rest_framework import serializers
class TodoSerializer(serializers.BaseSerializer):
class Meta:
model = Todo
fields = ['title', 'desc', 'level', 'created']
urls
from django.urls import path, include
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'todos', views.TodoViewSet)
urlpatterns = [
path('api/', include(router.urls)),
]
Many thanks in advance. Note: in case you're wondering is this all, this IS all as I jus started to learn drf a few moments ago.
you must use class TodoSerializer(serializers.ModelSerializer): not BaseSerializer
Related
I have the following in my views.py
I've been reading the documentation and trying to work out is there a way to exclude certain endpoints for this view.
from EoX.models import Vendor
from rest_framework import viewsets
from rest_framework import permissions
from .serializers import VendorSerializer
from url_filter.integrations.drf import DjangoFilterBackend
from drf_yasg.utils import swagger_auto_schema
from django.utils.decorators import method_decorator
class VendorViewSet(viewsets.ModelViewSet):
queryset = Vendor.objects.all()
serializer_class = VendorSerializer
permission_classes = [permissions.AllowAny]
filter_backends = [DjangoFilterBackend]
filter_fields = ['name',]
I can exclude the view all together with
schema=None
I tried decorating it with
#method_decorator(name='list', decorator=swagger_auto_schema(
operation_description="description from swagger_auto_schema via method_decorator"
))
and that changes the description of the 'get' endpoint.
but trying
#method_decorator(name='list', decorator=swagger_auto_schema(methods=['get'],
operation_description="description from swagger_auto_schema via method_decorator"
))
throws an error
AssertionError:methodormethodscan only be specified on #action or #api_view views
Is this a bug? or just not a supported feature, and is there a way to accomplish what I am trying?
Many thanks.
I am trying to build a Django (version 3.05) REST API call that will render to a chosen HTML template.
I am, however, receiving a number of errors that I haven't found a solution to on StackOverflow (And yes, I've looked far and wide).
Since my errors are many and varying depending on what I attempt, let me rather ask how to do it correctly to begin with.
In my view set up (below), what do I need to add (or change) in order to render the queryset to an HTML template?
models.py:
from django.db import models
class Hero(models.Model):
name = models.CharField(max_length=60)
alias = models.CharField(max_length=60)
def __str__(self):
return self.name
serializers.py:
from rest_framework import serializers
from .models import Hero
class HeroSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Hero
fields = ('name', 'alias')
views.py:
from rest_framework import viewsets
from .serializers import HeroSerializer
from .models import Hero
class HeroViewSet(viewsets.ModelViewSet):
queryset = Hero.objects.all().order_by('name')
serializer_class = HeroSerializer
# over here - how do I render the queryset /to/my/template.html
myapi/urls.py:
from django.urls import include, path
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(r'heroes', views.HeroViewSet)
you should change your view from ModelViewSet to APIView.
with API view you can include renderer_classes and template_name.
check here for more information
I am learning how to use class-based generic views but I keep getting a type error
from invoice.models import Invoice
from invoice.serializers import InvoiceSerializer
from rest_framework import generics
class InvoiceList(generics.ListCreateAPIView):
queryset = Invoice.objects.all()
serializer_class = InvoiceSerializer
class InvoiceDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Invoice.objects.all()
serializer_class = InvoiceSerializer
serialzers.py
from rest_framework import serializers
from .models import Invoice
class InvoiceSerializer(serializers.ModelSerializer):
class Meta:
model = Invoice
fields = "__all__"
urls.py
from django.urls import path
from invoice import views
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
path('invoice/', views.InvoiceList),
path('invoice/<int:pk>/', views.InvoiceDetail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
I get a type error with the message "init() takes 1 positional argument but 2 were given"
Your import in urls.py looks wrong.
In urls.py, try something like this:
from django.urls import path
from .views import InvoiceList
path('invoice/', InvoiceList.as_view(), name="invoice"), # name can be anything you want.
I never used the format_suffix_patterns, so you can try to take off that line to see if it works.
I am trying to understand Django RESTFramework. I am already familiar with Django. I want to create an endpoint that accepts some text data and processes it and returns it to the user along with the results of the processing (in text). I have completed a couple of tutorials on the topic but I still don't understand how it works. Here is an example from a working tutorial project. How can I edit it to achieve my goal? It all looks automagical.
# views.py
from rest_framework import generics
from .models import Snippet
from .serializers import SnippetSerializer
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
# Here I would like to accept form data and process it before returning it along with the
# results of the processing.
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
Okay, I think you are a newbie in Django rest and try to understand its flow so I can explain it with an example of a subscription plan.
First, create a model in models.py file
from django.db import models
class SubscriptionPlan(models.Model):
plan_name = models.CharField(max_length=255)
monthly_price = models.IntegerField()
yearly_price = models.IntegerField()
Then create views in a view.py file like
from rest_framework.views import APIView
class SubscriptionCreateAPIView(APIView):
serializer_class = SubscriptionSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(
{'message': 'Subscription plan created successfully.',
'data': serializer.data},
status=status.HTTP_201_CREATED
)
and then define a serializer for validation and fields in which we can verify which fields will be included in the request and response object.
serializers.py
from rest_framework import serializers
from .models import SubscriptionPlan
class SubscriptionSerializer(serializers.ModelSerializer):
plan_name = serializers.CharField(max_length=255)
monthly_price = serializers.IntegerField(required=True)
yearly_price = serializers.IntegerField(required=True)
class Meta:
model = SubscriptionPlan
fields = (
'plan_name', 'monthly_price', 'yearly_price',
)
def create(self, validated_data):
return SubscriptionPlan.objects.create(**validated_data)
Now add urls in src/subsciption_module/urls.py
from django.urls import path
from .views import SubscriptionCreateAPIView
app_name = 'subscription_plan'
urlpatterns = [
path('subscription_plan/', SubscriptionCreateAPIView.as_view()),
]
At the end include module url in root urls.py file where your main urls will be located. It will be the same directory which contains settings.py and wsgi.py files.
src/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('src.subscription_plan.urls', namespace='subscription_plan')),
]
That's it. This is how flow works in django rest and you can process data and display data in this way. For more details you can refer django rest docs.
But this is not in any way different from what you do with plain Django. Your SnippetDetail view is just a class-based view, and like any class-based view if you want to do anything specific you override the relevant method. In your case, you probably want to override update() to do your custom logic when receiving a PUT request to update data.
I try to create a view, that will accept POST requests and create new instances of my model(see bottom of post). I follow this tutorial. The problem is that when I access URL associated with view, which inherits from CreateAPIView I dont see a form in html representation of API for creation of new instances and I also see that it accepts GET requests, not POST as it mentioned in documentation.
Page looks like this
My views.py
from django.shortcuts import render
from rest_framework.generics import ListAPIView, CreateAPIView
from datingapp.models import Profile
from .serializers import ProfileSerializer, ProfileCreateSerializer
class ProfilesAPIView(ListAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
class ProfileCreateAPIView(CreateAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileCreateSerializer
My urls.py
from django.conf.urls import url
from django.contrib import admin
from datingapp.views import ProfilesAPIView, ProfileCreateAPIView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'api/profiles/', ProfilesAPIView.as_view(), name='list'),
url(r'api/profiles/create/$', ProfileCreateAPIView.as_view(), name='create')
]
My serializers.py
from rest_framework.serializers import ModelSerializer
from datingapp.models import Profile
class ProfileSerializer(ModelSerializer):
class Meta:
model = Profile
fields = [
'name',
'age',
'heigth'
'location',
]
class ProfileCreateSerializer(ModelSerializer):
class Meta:
model = Profile
fields = [
'name',
'age',
'heigth'
'location',
]
In my settings.py I have crispy_forms installed.
What am I doing wrong ?
UPD: here is what I want to achieve
As you see there is a form and it accepts only POST and also says that GET is not allowed
The problem is in your router. The first pattern matches both api/profiles/ and api/profiles/create/ so the second one will never be evaluated. You are seeing the ProfilesAPIView instead of the create view.
url(r'api/profiles/', ProfilesAPIView.as_view(), name='list'),
url(r'api/profiles/create/$', ProfileCreateAPIView.as_view(), name='create')
To fix it, either swap the order of the urls, or add a $ to the end of the first pattern. r'api/profiles/$'
I was following a tutorial and had a similar problem. Probably I was not following the same version of Django Rest Framework and they had changes.
But I solved this problem doing this.
class AssetBundleList(generics.ListAPIView):
to
class AssetBundleList(generics.ListCreateAPIView):
Hope this helps someone.