I'm using drf_yasg to create my swagger document but I have an issue with PaginationInspector. In one of my views I declare a paginator and in swagger, is shown as the default pagination for swagger.
Something like this:
count* integer #This info is generated automatically by swagger
next string($uri) #This info is generated automatically by swagger
x-nullable: true #This info is generated automatically by swagger
previous: string($uri) #This info is generated automatically by swagger
x-nullable: trueç
results: (THE BODY I ACTUALLY WANT TO SHOW)
I would like that the swagger ignore that pagination but haven’t found any info related to it.
I try using the decorator, initially I though it could be something like #swagger_auto_schema(paginator_inspectors=False) but it doesn't work and I can't find anything useful on the docs. Thanks in advance
oh and just in case this is my view:
class CharacterView(ListChView):
class OutputSerializer(serializers.Serializer):
id = serializers.CharField(source="external_id")
created_at = serializers.DateTimeField()
pagination_class = CustomPagination
Just override get_paginated_response_schema method.
class CustomPagination(PageNumberPagination):
...
# add
def get_paginated_response_schema(self, schema):
return {
'type': 'object',
'properties': {
'results': schema,
},
}
Related
Sorry if this is a noob question I am still learning. I have passed a variable from python code to a jinja2 HTML template to set up a URL, like this:
Delete
When this link is pressed it should run a query that deletes the entity with that ID. But when the link is pressed it goes to /delete/1827424298 for example, which results in a 404 error as the request handler doesn't exist.
I need to pass that ID back into my python code so it can run a method to delete the entity with that same ID. How do I go about doing this? Using webapp2 if that is important.
class DeleteRequestHandler(webapp2.RequestHandler):
def get():
template = template_env.get_template('myrequests.html')
context = {
'results': results.key.id()
}
self.response.out.write(template.render(context))
EDIT: I've added my delete handler - it is incomplete as I have yet to add the query to delete the entity. My thinking behind it so far is I can grab the results.key.id() from the jinja2 template and put it into results but I am not sure if this would work.
So I think what you're confused about is how to set up a route handler with a dynamic part to the URL. It's a shame that this is completely skipped over in the webapp2 tutorial, as it's a fundamental part of writing any web application. However, it is covered well in the guide to routing, which you should read.
At its simplest, it's just a matter of putting a regex in the route:
app = webapp2.WSGIApplication([
...
(r'/delete/(\d+)', MyDeleteHandler),
])
which will now route any URL of the form /delete/<number>/ to your deletion handler.
The ID that you pass in the URL will be the first positional argument to the handler method:
class MyDeleteHandler:
def get(self, item_id):
key = ndb.Key(MyModel, item_id) # or whatever
I'm using Django==1.10.5 and djangorestframework==3.5.3.
I have a few ModelViewSets that handle JSON API requests properly. Now, I'd like to use TemplateRenderer to add HTML rendering to those same ModelViewSets. I started with the list endpoint, and created a simple template that lists the available objects. I implemented the get_template_names to return the template I created.
Accessing that endpoint through the browser works fine when there are no objects to list, so everything related to setting up HTML renderers alongside APIs seems to work.However, when tere are objects to return the same endpoint fails with the following error:
ValueError: dictionary update sequence element #0 has length XX; 2 is required
Where XX is the number of attributes the object has.
This documentation section suggests the view function should act slightly differently when returning an HTML Response object, but I assume this is done by DRF's builtin views when necessary, so I don't think that's the issue.
This stackoverflow Q/A also looks relevant but I'm not quite sure it's the right solution to my problem.
How can I make my ModelViewSets work with both HTML and JSON renderers?
Thanks!
DRF has a brief explanation of how to do this in their documentation.
I think you'd do something like this...
On the client side, tell your endpoint what type of response you want:
fetch(yourAPIUrl, {
headers: {
'Accept': 'application/json'
// or 'Accept': 'text/html'
}
})
In your view, just check that and act accordingly:
class FlexibleAPIView(APIView):
"""
API view that can render either JSON or HTML.
"""
renderer_classes = [TemplateHTMLRenderer, JSONRenderer]
def get(self, request, *args, **kwargs):
queryset = Things.objects.all()
# If client wants HTML, give them HTML.
if request.accepted_renderer.format == 'html':
return Response({'things': queryset}, template_name='example.html')
# Otherwise, the client likely wants JSON so serialize the data.
serializer = ThingSerializer(instance=queryset)
data = serializer.data
return Response(data)
In my Django app I need to refresh part of a page via an Ajax call. The associated view returns a JsonResponse object, where one key in the context is the re-rendered HTML.
Something like this:
def myview(request):
...
tmpl8 = template.loader.get_template('page-table.html')
new_body = tmpl8.render({ 'rows': MyModel.custom_query() })
context = { 'new_body': new_body,
'other_info': other_information_for_javascript }
return JsonResponse(request, context)
Now, I also have context processors which add generic information. Some of this is needed in rendering page-table.html.
Unfortunately, context-processors don't get invoked by a bare Template.render(). They are invoked on the returned JsonResponse object, but it's too late by then as I've already rendered the template.
In Django 1.9 you can supply a RequestContext to Template.render and things go well - except for a Deprecation Warning appearing in the console. Django 1.10 insists that Template.render be given a dict.
So, the best I've been able to come up with is this:
from .context_processors import my_context_processor
def myview(request):
...
tmpl8 = template.loader.get_template('page-table.html')
render_context = { 'rows': MyModel.custom_query() }
render_context.update(my_context_processor(request))
new_body = tmpl8.render(render_context)
context = { 'new_body': new_body,
'other_info': other_information_for_javascript }
return JsonResponse(request, context)
Basically explicitly invoking the processor.
What am I missing?
Let's see what the render documentation says:
Template.render(context=None, request=None)
Renders this template
with a given context.
If context is provided, it must be a dict. If it isn’t provided, the
engine will render the template with an empty context.
If request is provided, it must be an HttpRequest. Then the engine
must make it, as well as the CSRF token, available in the template.
How this is achieved is up to each backend.
Here’s an example of the search algorithm. For this example the
TEMPLATES setting is:
The second parameter is the request! So we have
new_body = tmpl8.render(render_context, request)
Try to pass request to render() method:
new_body = tmpl8.render({ 'rows': MyModel.custom_query() }, request)
I'm building an API with django-rest-framework and I started using django-rest-swagger for documentation.
I have a nested serializer with some read_only fields, like this:
# this is the nested serializer
class Nested(serializers.Serializer):
normal_field = serializers.CharField(help_text="normal")
readonly_field = serializers.CharField(read_only=True,
help_text="readonly")
# this is the parent one
class Parent(serializers.Serializer):
nested_field = Nested()
In the generated docs, nested serializers in the Parameters part of the page are rendered with field data type and no hint is given about its content, they are just like other fields.
Now you can see the problem there, as I would like to inform the user that there is a readonly field that should not be sent as part of the nested data but I can not see a way of doing so.
The ideal would be having a model description in Data Type column, just like the Response Class section.
Is there any proper way of doing so?
1. of everything please use drf-yasg for documentation .
2. you can find its implementation in one of my repository Kirpi and learn how to use that.
3. if you in 3. ; have question,let me know.
Try to use drf_yasg instead, Swagger will generate the documentation for APIs, but it's not absolutely right!
If you want to correct Swagger documentation, you can do it. You will need to use swagger_auto_schema decorator. Below is the sample code:
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
class ProductSuspendView(CreateAPIView):
#swagger_auto_schema(
tags=['dashboard'],
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
'id': openapi.Schema(
type=openapi.TYPE_INTEGER,
description='Id',
),
'suspend_kinds': openapi.Schema(
type=openapi.TYPE_ARRAY,
items=openapi.Items(type=openapi.TYPE_INTEGER),
description='Array suspend (Inappropriate image: 1, Insufficient information: 2, Bad language: 3) (suspend_kinds=[1,2])'
),
}
),
responses={
status.HTTP_200_OK: SuccessResponseSerializer,
status.HTTP_400_BAD_REQUEST: ErrorResponseSerializer
}
)
def post(self, request, *args, **kwargs):
"""
Suspend a product.
"""
...
if success:
return Response({'success': True}, status.HTTP_200_OK)
return Response({'success': False}, status.HTTP_400_BAD_REQUEST)
This will going to be a very basic question that how to integrate Django with angularjs.I have developed a web application using Django.In views.py, i want to use json to dump my data from database but i don't have any idea or you can say i can't get started with the process.I have a very basic level knowledge about Angularjs.If you give some examples , then it will help me to get start in Angularjs using Django.For better convenience,here is a sample view that i have produced..
def userphoto(request):
user_photo = Photo.objects.get(user = request.user)
context = RequestContext(request)
ctx_dict = {'user_photo': user_photo}
return render_to_response('userena/profile_detail.html',ctx_dict,context)
here the ctx_dict directly rendering into a html file,but i want to render them using Angularjs probably using json and http get request to implement the data using Angularjs http service.How can i do this?in mention i am a novice in angularjs.
You can use django-angular, of cause, but I find this package too WIP.
You should think about AJAX instead of just rendering. It depends on a problem.
I'd suggest to use plain django or adding tastypie or django-rest-framework. I, currently, use plain django views.
Yes, to send models data back to angular, you should provide JSON of your data, you should serialize your model. But! There is a lot problems and catches. First of, you don't need everything from the model. Because user could access to some strange fields. Because you will send too many data you don't use on client side.
So, you should serialize your items data into JSON with fields you want. Here is example how I do it:
#ajax_request
#login_required
def mydata_ajax(request):
qs = MyData.objects.all()
#add possible filters
if request.GET.get('search'):
s = request.GET.get('search')
qs = qs.filter(
Q(name__icontains=s) |
Q(email__icontains=s) |
Q(address__icontains=s) |
)
qs = qs.order_by('task_time', 'name')
#setup pagination so angular will retrieve data page by page
pages = Paginator(qs, 20)
try:
current_page = int(request.GET.get('page', 1))
except ValueError:
current_page = 1
if current_page > pages.num_pages:
current_page = 1
#get reguested page
page = pages.page(current_page)
#create response
return {
'total': pages.count,
'num_pages': pages.num_pages,
'page': current_page,
'data': [{
'id': o.id,
'name': o.name,
'email': o.email,
'address': o.address,
} for o in page.object_list]
}
First of, I use ajax_request decorator, from django-annoying package, for my view, which expects view to return list, dictionary or any other simple data so it will automatically serialize(convert) it to JSON.
There is some handy things for you, like example of filters and pagination, btw.
have a look at
django-angular integration
django-angular-model-forms
django-angular