Add docstring documentation to the main InvenTree app

This commit is contained in:
Oliver Walters 2019-04-27 21:21:58 +10:00
parent c3f0570926
commit 5e6d49102d
7 changed files with 128 additions and 47 deletions

View File

@ -1,3 +1,7 @@
"""
Helper forms which subclass Django forms to provide additional functionality
"""
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
@ -6,6 +10,7 @@ from crispy_forms.helper import FormHelper
class HelperForm(forms.ModelForm):
""" Provides simple integration of crispy_forms extension. """
def __init__(self, *args, **kwargs):
super(forms.ModelForm, self).__init__(*args, **kwargs)

View File

@ -1,3 +1,7 @@
"""
Provides helper functions used throughout the InvenTree project
"""
import io
from wsgiref.util import FileWrapper
@ -5,7 +9,14 @@ from django.http import StreamingHttpResponse
def str2bool(text, test=True):
""" Test if a string 'looks' like a boolean value
""" Test if a string 'looks' like a boolean value.
Args:
text: Input text
test (default = True): Set which boolean value to look for
Returns:
True if the text looks like the selected boolean value
"""
if test:
return str(text).lower() in ['1', 'y', 'yes', 't', 'true', 'ok', ]
@ -13,21 +24,36 @@ def str2bool(text, test=True):
return str(text).lower() in ['0', 'n', 'no', 'none', 'f', 'false', ]
def WrapWithQuotes(text):
# TODO - Make this better
if not text.startswith('"'):
text = '"' + text
def WrapWithQuotes(text, quote='"'):
""" Wrap the supplied text with quotes
if not text.endswith('"'):
text = text + '"'
Args:
text: Input text to wrap
quote: Quote character to use for wrapping (default = "")
Returns:
Supplied text wrapped in quote char
"""
if not text.startswith(quote):
text = quote + text
if not text.endswith(quote):
text = text + quote
return text
def DownloadFile(data, filename, content_type='application/text'):
"""
Create a dynamic file for the user to download.
@param data is the raw file data
""" Create a dynamic file for the user to download.
Args:
data: Raw file data (string or bytes)
filename: Filename for the file download
content_type: Content type for the download
Return:
A StreamingHttpResponse object wrapping the supplied data
"""
filename = WrapWithQuotes(filename)

View File

@ -1,3 +1,7 @@
"""
Generic models which provide extra functionality over base Django model types.
"""
from __future__ import unicode_literals
from django.db import models
@ -11,6 +15,7 @@ from django.dispatch import receiver
class InvenTreeTree(models.Model):
""" Provides an abstracted self-referencing tree model for data categories.
- Each Category has one parent Category, which can be blank (for a top-level Category).
- Each Category can have zero-or-more child Categor(y/ies)
"""
@ -69,10 +74,12 @@ class InvenTreeTree(models.Model):
@property
def has_children(self):
""" True if there are any children under this item """
return self.children.count() > 0
@property
def children(self):
""" Return the children of this item """
contents = ContentType.objects.get_for_model(type(self))
childs = contents.get_all_objects_for_this_type(parent=self.id)
@ -100,11 +107,10 @@ class InvenTreeTree(models.Model):
@property
def parentpath(self):
""" Return the parent path of this category
""" Get the parent path of this category
Todo:
This function is recursive and expensive.
It should be reworked such that only a single db call is required
Returns:
List of category names from the top level to the parent of this category
"""
if self.parent:
@ -114,10 +120,21 @@ class InvenTreeTree(models.Model):
@property
def path(self):
""" Get the complete part of this category.
e.g. ["Top", "Second", "Third", "This"]
Returns:
List of category names from the top level to this category
"""
return self.parentpath + [self]
@property
def pathstring(self):
""" Get a string representation for the path of this item.
e.g. "Top/Second/Third/This"
"""
return '/'.join([item.name for item in self.path])
def __setattr__(self, attrname, val):
@ -157,38 +174,19 @@ class InvenTreeTree(models.Model):
super(InvenTreeTree, self).__setattr__(attrname, val)
def __str__(self):
""" String representation of a category is the full path to that category
Todo:
This is recursive - Make it not so.
"""
""" String representation of a category is the full path to that category """
return self.pathstring
@receiver(pre_delete, sender=InvenTreeTree, dispatch_uid='tree_pre_delete_log')
def before_delete_tree_item(sender, instance, using, **kwargs):
""" Receives pre_delete signal from InvenTreeTree object.
Before an item is deleted, update each child object to point to the parent of the object being deleted.
"""
# Update each tree item below this one
for child in instance.children.all():
child.parent = instance.parent
child.save()
def FilterChildren(queryset, parent):
""" Filter a queryset, limit to only objects that are a child of the given parent
Filter is passed in the URL string, e.g. '/?parent=123'
To accommodate for items without a parent, top-level items can be specified as:
none / false / null / top / 0
"""
if not parent:
return queryset
elif str2bool(parent, False):
return queryset.filter(parent=None)
else:
parent_id = int(parent)
if parent_id == 0:
return queryset.filter(parent=None)
else:
return queryset.filter(parent=parent_id)

View File

@ -1,3 +1,8 @@
"""
Serializers used in various InvenTree apps
"""
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
@ -7,6 +12,7 @@ from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
""" Serializer for User - provides all fields """
class Meta:
model = User
@ -14,6 +20,7 @@ class UserSerializer(serializers.ModelSerializer):
class UserSerializerBrief(serializers.ModelSerializer):
""" Serializer for User - provides limited information """
class Meta:
model = User

View File

@ -1,3 +1,10 @@
"""
Top-level URL lookup for InvenTree application.
Passes URL lookup downstream to each app as required.
"""
from django.conf.urls import url, include
from django.contrib import admin
from django.contrib.auth import views as auth_views

View File

@ -1,3 +1,10 @@
"""
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
@ -12,6 +19,8 @@ from rest_framework import views
class TreeSerializer(views.APIView):
""" JSON View for serializing a Tree object.
"""
def itemToJson(self, item):
@ -52,20 +61,34 @@ class TreeSerializer(views.APIView):
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_data(self):
""" Get extra context data (default implementation is empty dict)
Returns:
dict object (empty)
"""
return {}
def getAjaxTemplate(self):
if hasattr(self, 'ajax_template_name'):
return self.ajax_template_name
else:
return self.template_name
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
@ -73,7 +96,7 @@ class AjaxMixin(object):
data['title'] = self.ajax_form_title
data['html_form'] = render_to_string(
self.getAjaxTemplate(),
self.ajax_template_name,
context,
request=request
)
@ -88,7 +111,8 @@ class AjaxMixin(object):
class AjaxView(AjaxMixin, View):
""" Bare-bones AjaxView """
""" An 'AJAXified' View for displaying an object
"""
# By default, point to the modal_form template
# (this can be overridden by a child class)
@ -201,7 +225,7 @@ class AjaxDeleteView(AjaxMixin, DeleteView):
data = {'id': self.get_object().id,
'delete': False,
'title': self.ajax_form_title,
'html_data': render_to_string(self.getAjaxTemplate(),
'html_data': render_to_string(self.ajax_template_name,
self.get_context_data(),
request=request)
}
@ -229,15 +253,24 @@ class AjaxDeleteView(AjaxMixin, DeleteView):
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()

View File

@ -41,6 +41,8 @@ autoapi_dirs = [
autoapi_options = [
'members',
'private-members',
'special-members',
]
autoapi_type = 'python'
@ -51,6 +53,9 @@ autoapi_ignore = [
'**/manage.py',
'**/apps.py',
'**/admin.py',
'**/middleware.py',
'**/utils.py',
'**/wsgi.py',
'**/templates/',
]