Working on custom field info in metadata class

This commit is contained in:
Oliver 2021-06-24 13:12:46 +10:00
parent 9feef935f4
commit b350a971a4
2 changed files with 81 additions and 0 deletions

View File

@ -2,6 +2,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models
from collections import OrderedDict
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.utils.encoding import force_str
from rest_framework import exceptions, serializers, fields
from rest_framework.request import clone_request
from rest_framework.utils.field_mapping import ClassLookupDict
from rest_framework.metadata import SimpleMetadata from rest_framework.metadata import SimpleMetadata
import users.models import users.models
@ -17,6 +29,9 @@ class InvenTreeMetadata(SimpleMetadata):
Thus when a client send an OPTIONS request to an API endpoint, Thus when a client send an OPTIONS request to an API endpoint,
it will only receive a list of actions which it is allowed to perform! it will only receive a list of actions which it is allowed to perform!
Additionally, we include some extra information about database models,
so we can perform lookup for ForeignKey related fields.
""" """
def determine_metadata(self, request, view): def determine_metadata(self, request, view):
@ -73,3 +88,58 @@ class InvenTreeMetadata(SimpleMetadata):
pass pass
return metadata return metadata
def get_field_info(self, field):
"""
Given an instance of a serializer field, return a dictionary
of metadata about it.
"""
field_info = OrderedDict()
field_info['type'] = self.label_lookup[field]
field_info['required'] = getattr(field, 'required', False)
if field_info['type'] == 'field':
# If the field is a 'ForeignKey' field
if isinstance(field, serializers.ModelSerializer): # or isinstance(field, serializers.PrimaryKeyRelatedField):
model = field.Meta.model
# Construct the 'table name' from the model
app_label = model._meta.app_label
tbl_label = model._meta.model_name
table = f"{app_label}_{tbl_label}"
field_info['model'] = table
print(field_info['type'], field, type(field))
attrs = [
'read_only', 'label', 'help_text',
'min_length', 'max_length',
'min_value', 'max_value'
]
for attr in attrs:
value = getattr(field, attr, None)
if value is not None and value != '':
field_info[attr] = force_str(value, strings_only=True)
if getattr(field, 'child', None):
field_info['child'] = self.get_field_info(field.child)
elif getattr(field, 'fields', None):
field_info['children'] = self.get_serializer_info(field)
if (not field_info.get('read_only') and
not isinstance(field, (serializers.RelatedField, serializers.ManyRelatedField)) and
hasattr(field, 'choices')):
field_info['choices'] = [
{
'value': choice_value,
'display_name': force_str(choice_name, strings_only=True)
}
for choice_value, choice_name in field.choices.items()
]
return field_info

View File

@ -1,3 +1,6 @@
{% load i18n %}
{% load inventree_extras %}
/** /**
* This file contains code for rendering (and managing) HTML forms * This file contains code for rendering (and managing) HTML forms
* which are served via the django-drf API. * which are served via the django-drf API.
@ -229,16 +232,24 @@ function constructFormBody(url, fields, options={}) {
html += f; html += f;
} }
// TODO: Dynamically create the modals,
// so that we can have an infinite number of stacks!
var modal = '#modal-form'; var modal = '#modal-form';
modalEnable(modal, true); modalEnable(modal, true);
var title = options.title || '{% trans "Form Title" %}';
modalSetTitle(modal, title);
$(modal).find('.modal-form-content').html(html); $(modal).find('.modal-form-content').html(html);
$(modal).modal('show'); $(modal).modal('show');
attachToggle(modal); attachToggle(modal);
attachSelect(modal); attachSelect(modal);
modalShowSubmitButton(modal, true);
} }