mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Add docstring documentation to the main InvenTree app
This commit is contained in:
		| @@ -1,3 +1,7 @@ | |||||||
|  | """  | ||||||
|  | Helper forms which subclass Django forms to provide additional functionality | ||||||
|  | """ | ||||||
|  |  | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| @@ -6,6 +10,7 @@ from crispy_forms.helper import FormHelper | |||||||
|  |  | ||||||
|  |  | ||||||
| class HelperForm(forms.ModelForm): | class HelperForm(forms.ModelForm): | ||||||
|  |     """ Provides simple integration of crispy_forms extension. """ | ||||||
|  |  | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
|         super(forms.ModelForm, self).__init__(*args, **kwargs) |         super(forms.ModelForm, self).__init__(*args, **kwargs) | ||||||
|   | |||||||
| @@ -1,3 +1,7 @@ | |||||||
|  | """ | ||||||
|  | Provides helper functions used throughout the InvenTree project | ||||||
|  | """ | ||||||
|  |  | ||||||
| import io | import io | ||||||
|  |  | ||||||
| from wsgiref.util import FileWrapper | from wsgiref.util import FileWrapper | ||||||
| @@ -5,7 +9,14 @@ from django.http import StreamingHttpResponse | |||||||
|  |  | ||||||
|  |  | ||||||
| def str2bool(text, test=True): | 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: |     if test: | ||||||
|         return str(text).lower() in ['1', 'y', 'yes', 't', 'true', 'ok', ] |         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', ] |         return str(text).lower() in ['0', 'n', 'no', 'none', 'f', 'false', ] | ||||||
|  |  | ||||||
|  |  | ||||||
| def WrapWithQuotes(text): | def WrapWithQuotes(text, quote='"'): | ||||||
|     # TODO - Make this better |     """ Wrap the supplied text with quotes | ||||||
|     if not text.startswith('"'): |  | ||||||
|         text = '"' + text |  | ||||||
|  |  | ||||||
|     if not text.endswith('"'): |     Args: | ||||||
|         text = text + '"' |         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 |     return text | ||||||
|  |  | ||||||
|  |  | ||||||
| def DownloadFile(data, filename, content_type='application/text'): | def DownloadFile(data, filename, content_type='application/text'): | ||||||
|     """ |     """ Create a dynamic file for the user to download. | ||||||
|     Create a dynamic file for the user to download. |      | ||||||
|     @param data is the raw file data |     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) |     filename = WrapWithQuotes(filename) | ||||||
|   | |||||||
| @@ -1,3 +1,7 @@ | |||||||
|  | """ | ||||||
|  | Generic models which provide extra functionality over base Django model types. | ||||||
|  | """ | ||||||
|  |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| from django.db import models | from django.db import models | ||||||
| @@ -11,6 +15,7 @@ from django.dispatch import receiver | |||||||
|  |  | ||||||
| class InvenTreeTree(models.Model): | class InvenTreeTree(models.Model): | ||||||
|     """ Provides an abstracted self-referencing tree model for data categories. |     """ 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 has one parent Category, which can be blank (for a top-level Category). | ||||||
|     - Each Category can have zero-or-more child Categor(y/ies) |     - Each Category can have zero-or-more child Categor(y/ies) | ||||||
|     """ |     """ | ||||||
| @@ -69,10 +74,12 @@ class InvenTreeTree(models.Model): | |||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def has_children(self): |     def has_children(self): | ||||||
|  |         """ True if there are any children under this item """ | ||||||
|         return self.children.count() > 0 |         return self.children.count() > 0 | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def children(self): |     def children(self): | ||||||
|  |         """ Return the children of this item """ | ||||||
|         contents = ContentType.objects.get_for_model(type(self)) |         contents = ContentType.objects.get_for_model(type(self)) | ||||||
|         childs = contents.get_all_objects_for_this_type(parent=self.id) |         childs = contents.get_all_objects_for_this_type(parent=self.id) | ||||||
|  |  | ||||||
| @@ -100,11 +107,10 @@ class InvenTreeTree(models.Model): | |||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def parentpath(self): |     def parentpath(self): | ||||||
|         """ Return the parent path of this category |         """ Get the parent path of this category | ||||||
|  |  | ||||||
|         Todo: |         Returns: | ||||||
|             This function is recursive and expensive. |             List of category names from the top level to the parent of this category | ||||||
|             It should be reworked such that only a single db call is required |  | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         if self.parent: |         if self.parent: | ||||||
| @@ -114,10 +120,21 @@ class InvenTreeTree(models.Model): | |||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def path(self): |     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] |         return self.parentpath + [self] | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def pathstring(self): |     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]) |         return '/'.join([item.name for item in self.path]) | ||||||
|  |  | ||||||
|     def __setattr__(self, attrname, val): |     def __setattr__(self, attrname, val): | ||||||
| @@ -157,38 +174,19 @@ class InvenTreeTree(models.Model): | |||||||
|         super(InvenTreeTree, self).__setattr__(attrname, val) |         super(InvenTreeTree, self).__setattr__(attrname, val) | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         """ String representation of a category is the full path to that category |         """ String representation of a category is the full path to that category """ | ||||||
|  |  | ||||||
|         Todo: |  | ||||||
|             This is recursive - Make it not so. |  | ||||||
|         """ |  | ||||||
|  |  | ||||||
|         return self.pathstring |         return self.pathstring | ||||||
|  |  | ||||||
|  |  | ||||||
| @receiver(pre_delete, sender=InvenTreeTree, dispatch_uid='tree_pre_delete_log') | @receiver(pre_delete, sender=InvenTreeTree, dispatch_uid='tree_pre_delete_log') | ||||||
| def before_delete_tree_item(sender, instance, using, **kwargs): | 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 |     # Update each tree item below this one | ||||||
|     for child in instance.children.all(): |     for child in instance.children.all(): | ||||||
|         child.parent = instance.parent |         child.parent = instance.parent | ||||||
|         child.save() |         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) |  | ||||||
|   | |||||||
| @@ -1,3 +1,8 @@ | |||||||
|  | """  | ||||||
|  | Serializers used in various InvenTree apps | ||||||
|  | """ | ||||||
|  |  | ||||||
|  |  | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| @@ -7,6 +12,7 @@ from django.contrib.auth.models import User | |||||||
|  |  | ||||||
|  |  | ||||||
| class UserSerializer(serializers.ModelSerializer): | class UserSerializer(serializers.ModelSerializer): | ||||||
|  |     """ Serializer for User - provides all fields """ | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|         model = User |         model = User | ||||||
| @@ -14,6 +20,7 @@ class UserSerializer(serializers.ModelSerializer): | |||||||
|  |  | ||||||
|  |  | ||||||
| class UserSerializerBrief(serializers.ModelSerializer): | class UserSerializerBrief(serializers.ModelSerializer): | ||||||
|  |     """ Serializer for User - provides limited information """ | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|         model = User |         model = User | ||||||
|   | |||||||
| @@ -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.conf.urls import url, include | ||||||
| from django.contrib import admin | from django.contrib import admin | ||||||
| from django.contrib.auth import views as auth_views | from django.contrib.auth import views as auth_views | ||||||
|   | |||||||
| @@ -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 -*- | # -*- coding: utf-8 -*- | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| @@ -12,6 +19,8 @@ from rest_framework import views | |||||||
|  |  | ||||||
|  |  | ||||||
| class TreeSerializer(views.APIView): | class TreeSerializer(views.APIView): | ||||||
|  |     """ JSON View for serializing a Tree object. | ||||||
|  |     """  | ||||||
|  |  | ||||||
|     def itemToJson(self, item): |     def itemToJson(self, item): | ||||||
|  |  | ||||||
| @@ -52,20 +61,34 @@ class TreeSerializer(views.APIView): | |||||||
|  |  | ||||||
|  |  | ||||||
| class AjaxMixin(object): | 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_action = '' | ||||||
|     ajax_form_title = '' |     ajax_form_title = '' | ||||||
|  |  | ||||||
|     def get_data(self): |     def get_data(self): | ||||||
|  |         """ Get extra context data (default implementation is empty dict) | ||||||
|  |  | ||||||
|  |         Returns: | ||||||
|  |             dict object (empty) | ||||||
|  |         """ | ||||||
|         return {} |         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={}): |     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: |         if form: | ||||||
|             context['form'] = form |             context['form'] = form | ||||||
| @@ -73,7 +96,7 @@ class AjaxMixin(object): | |||||||
|         data['title'] = self.ajax_form_title |         data['title'] = self.ajax_form_title | ||||||
|  |  | ||||||
|         data['html_form'] = render_to_string( |         data['html_form'] = render_to_string( | ||||||
|             self.getAjaxTemplate(), |             self.ajax_template_name, | ||||||
|             context, |             context, | ||||||
|             request=request |             request=request | ||||||
|         ) |         ) | ||||||
| @@ -88,7 +111,8 @@ class AjaxMixin(object): | |||||||
|  |  | ||||||
|  |  | ||||||
| class AjaxView(AjaxMixin, View): | class AjaxView(AjaxMixin, View): | ||||||
|     """ Bare-bones AjaxView """ |     """ An 'AJAXified' View for displaying an object | ||||||
|  |     """ | ||||||
|  |  | ||||||
|     # By default, point to the modal_form template |     # By default, point to the modal_form template | ||||||
|     # (this can be overridden by a child class) |     # (this can be overridden by a child class) | ||||||
| @@ -201,7 +225,7 @@ class AjaxDeleteView(AjaxMixin, DeleteView): | |||||||
|             data = {'id': self.get_object().id, |             data = {'id': self.get_object().id, | ||||||
|                     'delete': False, |                     'delete': False, | ||||||
|                     'title': self.ajax_form_title, |                     '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(), |                                                   self.get_context_data(), | ||||||
|                                                   request=request) |                                                   request=request) | ||||||
|                     } |                     } | ||||||
| @@ -229,15 +253,24 @@ class AjaxDeleteView(AjaxMixin, DeleteView): | |||||||
|  |  | ||||||
|  |  | ||||||
| class IndexView(TemplateView): | class IndexView(TemplateView): | ||||||
|  |     """ View for InvenTree index page """ | ||||||
|  |  | ||||||
|     template_name = 'InvenTree/index.html' |     template_name = 'InvenTree/index.html' | ||||||
|  |  | ||||||
|  |  | ||||||
| class SearchView(TemplateView): | class SearchView(TemplateView): | ||||||
|  |     """ View for InvenTree search page.  | ||||||
|  |  | ||||||
|  |     Displays results of search query | ||||||
|  |     """ | ||||||
|  |  | ||||||
|     template_name = 'InvenTree/search.html' |     template_name = 'InvenTree/search.html' | ||||||
|  |  | ||||||
|     def post(self, request, *args, **kwargs): |     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() |         context = self.get_context_data() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,6 +41,8 @@ autoapi_dirs = [ | |||||||
|  |  | ||||||
| autoapi_options = [ | autoapi_options = [ | ||||||
|     'members', |     'members', | ||||||
|  |     'private-members', | ||||||
|  |     'special-members', | ||||||
| ] | ] | ||||||
|  |  | ||||||
| autoapi_type = 'python' | autoapi_type = 'python' | ||||||
| @@ -51,6 +53,9 @@ autoapi_ignore = [ | |||||||
|     '**/manage.py', |     '**/manage.py', | ||||||
|     '**/apps.py', |     '**/apps.py', | ||||||
|     '**/admin.py', |     '**/admin.py', | ||||||
|  |     '**/middleware.py', | ||||||
|  |     '**/utils.py', | ||||||
|  |     '**/wsgi.py', | ||||||
|     '**/templates/', |     '**/templates/', | ||||||
| ] | ] | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user