2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-30 12:36:45 +00:00
Oliver Walters 29f7b1a32b Revert "More intelligent passing of context data in AjaxView"
This reverts commit fbb9a708f560f841fab50b811ea1b5a32cf20521.
2019-05-01 22:52:33 +10:00

305 lines
7.9 KiB
Python

"""
Various Views which provide extra functionality over base Django Views.
In particular these views provide base functionality for rendering Django forms
as JSON objects and passing them to modal forms (using jQuery / bootstrap).
"""
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.template.loader import render_to_string
from django.http import JsonResponse
from django.views import View
from django.views.generic import UpdateView, CreateView, DeleteView
from django.views.generic.base import TemplateView
from rest_framework import views
class TreeSerializer(views.APIView):
""" JSON View for serializing a Tree object.
"""
def itemToJson(self, item):
data = {
'text': item.name,
'href': item.get_absolute_url(),
}
if item.has_children:
nodes = []
for child in item.children.all().order_by('name'):
nodes.append(self.itemToJson(child))
data['nodes'] = nodes
return data
def get(self, request, *args, **kwargs):
top_items = self.model.objects.filter(parent=None).order_by('name')
nodes = []
for item in top_items:
nodes.append(self.itemToJson(item))
top = {
'text': self.title,
'nodes': nodes,
}
response = {
'tree': [top]
}
return JsonResponse(response, safe=False)
class AjaxMixin(object):
""" AjaxMixin provides basic functionality for rendering a Django form to JSON.
Handles jsonResponse rendering, and adds extra data for the modal forms to process
on the client side.
"""
ajax_form_action = ''
ajax_form_title = ''
def get_param(self, name, method='GET'):
""" Get a request query parameter value from URL e.g. ?part=3
Args:
name: Variable name e.g. 'part'
method: Request type ('GET' or 'POST')
Returns:
Value of the supplier parameter or None if parameter is not available
"""
if method == 'POST':
return self.request.POST.get(name, None)
else:
return self.request.GET.get(name, None)
def get_data(self):
""" Get extra context data (default implementation is empty dict)
Returns:
dict object (empty)
"""
return {}
def renderJsonResponse(self, request, form=None, data={}, context={}):
""" Render a JSON response based on specific class context.
Args:
request: HTTP request object (e.g. GET / POST)
form: Django form object (may be None)
data: Extra JSON data to pass to client
context: Extra context data to pass to template rendering
Returns:
JSON response object
"""
if form:
context['form'] = form
data['title'] = self.ajax_form_title
data['html_form'] = render_to_string(
self.ajax_template_name,
context,
request=request
)
# Custom feedback`data
fb = self.get_data()
for key in fb.keys():
data[key] = fb[key]
return JsonResponse(data, safe=False)
class AjaxView(AjaxMixin, View):
""" An 'AJAXified' View for displaying an object
"""
# By default, point to the modal_form template
# (this can be overridden by a child class)
ajax_template_name = 'modal_form.html'
def post(self, request, *args, **kwargs):
return JsonResponse('', safe=False)
def get(self, request, *args, **kwargs):
return self.renderJsonResponse(request)
class AjaxCreateView(AjaxMixin, CreateView):
""" An 'AJAXified' CreateView for creating a new object in the db
- Returns a form in JSON format (for delivery to a modal window)
- Handles form validation via AJAX POST requests
"""
def get(self, request, *args, **kwargs):
""" Creates form with initial data, and renders JSON response """
super(CreateView, self).get(request, *args, **kwargs)
form = self.get_form()
return self.renderJsonResponse(request, form)
def post(self, request, *args, **kwargs):
""" Responds to form POST. Validates POST data and returns status info.
- Validate POST form data
- If valid, save form
- Return status info (success / failure)
"""
form = self.get_form()
# Extra JSON data sent alongside form
data = {
'form_valid': form.is_valid(),
}
if form.is_valid():
obj = form.save()
# Return the PK of the newly-created object
data['pk'] = obj.pk
data['url'] = obj.get_absolute_url()
return self.renderJsonResponse(request, form, data)
class AjaxUpdateView(AjaxMixin, UpdateView):
""" An 'AJAXified' UpdateView for updating an object in the db
- Returns form in JSON format (for delivery to a modal window)
- Handles repeated form validation (via AJAX) until the form is valid
"""
def get(self, request, *args, **kwargs):
""" Respond to GET request.
- Populates form with object data
- Renders form to JSON and returns to client
"""
super(UpdateView, self).get(request, *args, **kwargs)
form = self.get_form()
return self.renderJsonResponse(request, form)
def post(self, request, *args, **kwargs):
""" Respond to POST request.
- Updates model with POST field data
- Performs form and object validation
- If errors exist, re-render the form
- Otherwise, return sucess status
"""
super(UpdateView, self).post(request, *args, **kwargs)
form = self.get_form()
data = {
'form_valid': form.is_valid()
}
if form.is_valid():
obj = form.save()
# Include context data about the updated object
data['pk'] = obj.id
data['url'] = obj.get_absolute_url()
return self.renderJsonResponse(request, form, data)
class AjaxDeleteView(AjaxMixin, DeleteView):
""" An 'AJAXified DeleteView for removing an object from the DB
- Returns a HTML object (not a form!) in JSON format (for delivery to a modal window)
- Handles deletion
"""
def get(self, request, *args, **kwargs):
""" Respond to GET request
- Render a DELETE confirmation form to JSON
- Return rendered form to client
"""
super(DeleteView, self).get(request, *args, **kwargs)
data = {
'id': self.get_object().id,
'delete': False,
'title': self.ajax_form_title,
'html_data': render_to_string(
self.ajax_template_name,
self.get_context_data(),
request=request)
}
return JsonResponse(data)
def post(self, request, *args, **kwargs):
""" Respond to POST request
- DELETE the object
- Render success message to JSON and return to client
"""
obj = self.get_object()
pk = obj.id
obj.delete()
data = {
'id': pk,
'delete': True
}
return self.renderJsonResponse(request, data=data)
class IndexView(TemplateView):
""" View for InvenTree index page """
template_name = 'InvenTree/index.html'
class SearchView(TemplateView):
""" View for InvenTree search page.
Displays results of search query
"""
template_name = 'InvenTree/search.html'
def post(self, request, *args, **kwargs):
""" Handle POST request (which contains search query).
Pass the search query to the page template
"""
context = self.get_context_data()
query = request.POST.get('search', '')
context['query'] = query
return super(TemplateView, self).render_to_response(context)