mirror of
https://github.com/Hopiu/django-fobi.git
synced 2026-05-18 01:21:07 +00:00
prepare 0.5.8; dynamic initial values; minor fixes/improvements
This commit is contained in:
parent
d974e27a8e
commit
210f517787
18 changed files with 306 additions and 52 deletions
|
|
@ -15,6 +15,15 @@ are used for versioning (schema follows below):
|
|||
0.3.4 to 0.4).
|
||||
- All backwards incompatible changes are mentioned in this document.
|
||||
|
||||
|
||||
0.5.8
|
||||
-----
|
||||
2015-08-16
|
||||
|
||||
- Made it possible to define dynamic initials for form fields. Example initial
|
||||
dynamic values in the form (like {{ request.path }}).
|
||||
- Minor fixes/improvements.
|
||||
|
||||
0.5.7
|
||||
-----
|
||||
2015-08-03
|
||||
|
|
|
|||
44
README.rst
44
README.rst
|
|
@ -83,6 +83,7 @@ Main features and highlights
|
|||
- Data export (`db_store
|
||||
<https://github.com/barseghyanartur/django-fobi/tree/stable/src/fobi/contrib/plugins/form_handlers/db_store>`_
|
||||
form handler plugin) into XLS/CSV format.
|
||||
- Dynamic initial values for form elements.
|
||||
|
||||
Roadmap
|
||||
=======
|
||||
|
|
@ -1423,6 +1424,49 @@ should be constructing your URL to the form as follows:
|
|||
|
||||
http://127.0.0.1:8001/fobi/view/test-form/?fobi_initial_data&email=test@example.com&age=19
|
||||
|
||||
Dynamic initial values
|
||||
======================
|
||||
It's possible to provide a dynamic initial value for any of the elements.
|
||||
In order to do that, you should use the build-in context processor or make
|
||||
your own one. The only requirement is that you should store all values that
|
||||
should be exposes in the form as a dict for `fobi_dynamic_values` dictionary
|
||||
key. Beware, that passing the original request object might be unsafe in
|
||||
many ways. Currently, a stripped down version of the request object is being
|
||||
passed as a context variable.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
# ...
|
||||
"fobi.context_processors.dynamic_values",
|
||||
# ...
|
||||
)
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def dynamic_values(request):
|
||||
return {
|
||||
'fobi_dynamic_values': {
|
||||
'request': StrippedRequest(request),
|
||||
'now': datetime.datetime.now(),
|
||||
'today': datetime.date.today(),
|
||||
}
|
||||
}
|
||||
|
||||
In your GUI, you should be refering to the initial values in the following way:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
{{ request.path }} {{ now }} {{ today }}
|
||||
|
||||
Notice, that you should not provide the `fobi_dynamic_values.` as a prefix.
|
||||
Currently, the following variables are available in the
|
||||
`fobi.context_processors.dynamic_values` context processor:
|
||||
|
||||
- request: Stripped HttpRequest object.
|
||||
- now: datetime.datetime.now()
|
||||
- today: datetime.date.today()
|
||||
|
||||
Submitted form element plugins values
|
||||
=====================================
|
||||
While some values of form element plugins are submitted as is, some others
|
||||
|
|
|
|||
|
|
@ -23,13 +23,11 @@ change of the name of the "simple" theme into "django_admin_style" theme.
|
|||
- Internally, make a date when form has been created. Also keep track of when
|
||||
the form has been last edited.
|
||||
|
||||
0.5.8
|
||||
0.5.9
|
||||
-----
|
||||
yyyy-mm-dd (upcoming).
|
||||
|
||||
- Export/import forms saved as JSON. Validate the imports and mention that
|
||||
some plugins are not installed if there are plugins that should be installed
|
||||
first.
|
||||
- Made it possible to define dynamic fields and use then in the form. Let
|
||||
developers themselves define what should be in there and the contents of it
|
||||
(pluggable and replaceable).
|
||||
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ Must haves
|
|||
developers themselves define what should be in there (some sort of
|
||||
register in global scope, maybe just a context processor).
|
||||
Make it pluggable and replaceable.
|
||||
- Check if it's safe to use the initial dynamic values.
|
||||
|
||||
Should haves
|
||||
============
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ Main features and highlights
|
|||
- Data export (`db_store
|
||||
<https://github.com/barseghyanartur/django-fobi/tree/stable/src/fobi/contrib/plugins/form_handlers/db_store>`_
|
||||
form handler plugin) into XLS/CSV format.
|
||||
- Dynamic initial values for form elements.
|
||||
|
||||
Roadmap
|
||||
=======
|
||||
|
|
@ -1423,6 +1424,49 @@ should be constructing your URL to the form as follows:
|
|||
|
||||
http://127.0.0.1:8001/fobi/view/test-form/?fobi_initial_data&email=test@example.com&age=19
|
||||
|
||||
Dynamic initial values
|
||||
======================
|
||||
It's possible to provide a dynamic initial value for any of the elements.
|
||||
In order to do that, you should use the build-in context processor or make
|
||||
your own one. The only requirement is that you should store all values that
|
||||
should be exposes in the form as a dict for `fobi_dynamic_values` dictionary
|
||||
key. Beware, that passing the original request object might be unsafe in
|
||||
many ways. Currently, a stripped down version of the request object is being
|
||||
passed as a context variable.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
# ...
|
||||
"fobi.context_processors.dynamic_values",
|
||||
# ...
|
||||
)
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def dynamic_values(request):
|
||||
return {
|
||||
'fobi_dynamic_values': {
|
||||
'request': StrippedRequest(request),
|
||||
'now': datetime.datetime.now(),
|
||||
'today': datetime.date.today(),
|
||||
}
|
||||
}
|
||||
|
||||
In your GUI, you should be refering to the initial values in the following way:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
{{ request.path }} {{ now }} {{ today }}
|
||||
|
||||
Notice, that you should not provide the `fobi_dynamic_values.` as a prefix.
|
||||
Currently, the following variables are available in the
|
||||
`fobi.context_processors.dynamic_values` context processor:
|
||||
|
||||
- request: Stripped HttpRequest object.
|
||||
- now: datetime.datetime.now()
|
||||
- today: datetime.date.today()
|
||||
|
||||
Submitted form element plugins values
|
||||
=====================================
|
||||
While some values of form element plugins are submitted as is, some others
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
|
|||
"django.contrib.messages.context_processors.messages",
|
||||
"django.core.context_processors.request",
|
||||
"fobi.context_processors.theme", # Important!
|
||||
"fobi.context_processors.dynamic_values", # Optional
|
||||
)
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -67,7 +67,7 @@ for static_dir in static_dirs:
|
|||
for locale_dir in locale_dirs:
|
||||
locale_files += [os.path.join(locale_dir, f) for f in os.listdir(locale_dir)]
|
||||
|
||||
version = '0.5.7'
|
||||
version = '0.5.8'
|
||||
|
||||
install_requires = [
|
||||
'Pillow>=2.0.0',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
__title__ = 'django-fobi'
|
||||
__version__ = '0.5.7'
|
||||
__build__ = 0x00003c
|
||||
__version__ = '0.5.8'
|
||||
__build__ = 0x00003d
|
||||
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
|
||||
__copyright__ = '2014-2015 Artur Barseghyan'
|
||||
__license__ = 'GPL 2.0/LGPL 2.1'
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ from django import forms
|
|||
from django.forms import ModelForm
|
||||
from django.http import Http404
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.test import RequestFactory
|
||||
from django.template import RequestContext, Template, Context
|
||||
|
||||
from nine.versions import DJANGO_GTE_1_8
|
||||
|
||||
|
|
@ -73,7 +76,8 @@ from fobi.exceptions import (
|
|||
)
|
||||
from fobi.helpers import (
|
||||
uniquify_sequence, map_field_name_to_label, clean_dict,
|
||||
map_field_name_to_label, get_ignorable_form_values, safe_text
|
||||
map_field_name_to_label, get_ignorable_form_values, safe_text,
|
||||
StrippedRequest,
|
||||
)
|
||||
from fobi.data_structures import SortableDict
|
||||
|
||||
|
|
@ -1118,9 +1122,9 @@ class FormElementPlugin(BasePlugin):
|
|||
has_value = False
|
||||
is_hidden = False
|
||||
|
||||
def _get_form_field_instances(self, form_element_entry=None, origin=None, \
|
||||
kwargs_update_func=None, return_func=None, \
|
||||
extra={}):
|
||||
def _get_form_field_instances(self, form_element_entry=None, origin=None,
|
||||
kwargs_update_func=None, return_func=None,
|
||||
extra={}, request=None):
|
||||
"""
|
||||
Used internally. Do not override this method. Gets the instances of
|
||||
form fields, that plugin contains.
|
||||
|
|
@ -1154,6 +1158,29 @@ class FormElementPlugin(BasePlugin):
|
|||
Widget = None
|
||||
if isinstance(Field, (list, tuple)):
|
||||
Field, Widget = Field
|
||||
|
||||
# Consider using context for resolving some variables.
|
||||
# For instance, if user is logged in, ``request.user.username``
|
||||
# as an initial value should put the current users' username
|
||||
# as initial value in the form.
|
||||
if 'initial' in field_kwargs and field_kwargs['initial']:
|
||||
# For security reasons we're not using the original request
|
||||
# here.
|
||||
stripped_request = StrippedRequest(request)
|
||||
context = RequestContext(stripped_request)
|
||||
|
||||
# In order to be sure, that no accidental sensitive data
|
||||
# is exposed in the forms, we only vales from the
|
||||
# fobi specific context processor. By automatically
|
||||
# force-prefixing all dynamic value definitions with
|
||||
# "fobi_dynamic_values." string. See the docs for
|
||||
# more ("Dyamic initial values" section).
|
||||
initial = field_kwargs['initial']
|
||||
initial = initial.replace("{{ ", "{{") \
|
||||
.replace(" }}", "}}") \
|
||||
.replace("{{", "{{fobi_dynamic_values.")
|
||||
field_kwargs['initial'] = Template(initial).render(context)
|
||||
|
||||
# Data to update field instance kwargs with
|
||||
kwargs_update = self.get_origin_kwargs_update_func_results(
|
||||
kwargs_update_func,
|
||||
|
|
|
|||
|
|
@ -9,13 +9,14 @@ from django.conf import settings
|
|||
from nine.user import User
|
||||
|
||||
# Sanity checks. Possibly rely on the dynamic username field in future.
|
||||
user = User()
|
||||
|
||||
if not hasattr(user, 'username'):
|
||||
from dash.exceptions import ImproperlyConfigured
|
||||
raise ImproperlyConfigured("Your custom user model ({0}.{1}) doesn't "
|
||||
"have ``username`` property, while "
|
||||
"``django-fobi`` relies on its' presence."
|
||||
"".format(user._meta.app_label, user._meta.object_name))
|
||||
#user = User()
|
||||
#
|
||||
#if not hasattr(user, 'username'):
|
||||
# from fobi.exceptions import ImproperlyConfigured
|
||||
# raise ImproperlyConfigured("Your custom user model ({0}.{1}) doesn't "
|
||||
# "have ``username`` property, while "
|
||||
# "``django-fobi`` relies on its' presence."
|
||||
# "".format(user._meta.app_label,
|
||||
# user._meta.object_name))
|
||||
|
||||
AUTH_USER_MODEL = settings.AUTH_USER_MODEL
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ __copyright__ = 'Copyright (c) 2014 Artur Barseghyan'
|
|||
__license__ = 'GPL 2.0/LGPL 2.1'
|
||||
__all__ = ('theme',)
|
||||
|
||||
import datetime
|
||||
|
||||
from fobi.base import get_theme
|
||||
from fobi.helpers import StrippedRequest
|
||||
|
||||
def theme(request):
|
||||
"""
|
||||
|
|
@ -14,3 +17,15 @@ def theme(request):
|
|||
:return fobi.base.BaseTheme: Instance of ``fobi.base.BaseTheme``.
|
||||
"""
|
||||
return {'fobi_theme': get_theme(request, as_instance=True)}
|
||||
|
||||
def dynamic_values(request):
|
||||
"""
|
||||
Dynamic values exposed to public forms.
|
||||
"""
|
||||
return {
|
||||
'fobi_dynamic_values': {
|
||||
'request': StrippedRequest(request),
|
||||
'now': datetime.datetime.now(),
|
||||
'today': datetime.date.today(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ from django.forms.widgets import media_property
|
|||
# ****************************************************************************
|
||||
# ****************************************************************************
|
||||
|
||||
def assemble_form_class(form_entry, base_class=BaseForm, request=None, \
|
||||
origin=None, origin_kwargs_update_func=None, \
|
||||
def assemble_form_class(form_entry, base_class=BaseForm, request=None,
|
||||
origin=None, origin_kwargs_update_func=None,
|
||||
origin_return_func=None, form_element_entries=None):
|
||||
"""
|
||||
Assembles a form class by given entry.
|
||||
|
|
@ -53,14 +53,15 @@ def assemble_form_class(form_entry, base_class=BaseForm, request=None, \
|
|||
|
||||
# We simply make sure the plugin exists. We don't handle
|
||||
# exceptions relate to the non-existent plugins here. They
|
||||
# are istead handled in registry.
|
||||
# are instead handled in registry.
|
||||
if plugin:
|
||||
plugin_form_field_instances = plugin._get_form_field_instances(
|
||||
form_element_entry = form_element_entry,
|
||||
origin = origin,
|
||||
kwargs_update_func = origin_kwargs_update_func,
|
||||
return_func = origin_return_func,
|
||||
extra = {'counter': creation_counter}
|
||||
extra = {'counter': creation_counter},
|
||||
request = request
|
||||
)
|
||||
for form_field_name, form_field_instance in plugin_form_field_instances:
|
||||
base_fields.append((form_field_name, form_field_instance))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ __all__ = (
|
|||
'update_plugin_data', 'get_select_field_choices',
|
||||
'validate_initial_for_choices', 'validate_initial_for_multiple_choices',
|
||||
'validate_submit_value_as', 'get_app_label_and_model_name',
|
||||
'StrippedUser', 'StrippedRequest',
|
||||
)
|
||||
|
||||
import os
|
||||
|
|
@ -34,9 +35,13 @@ from django.db.utils import DatabaseError
|
|||
from django.utils.encoding import force_text
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from autoslug.settings import slugify
|
||||
|
||||
from nine.user import User
|
||||
|
||||
from fobi.constants import (
|
||||
SUBMIT_VALUE_AS_VAL, SUBMIT_VALUE_AS_REPR, SUBMIT_VALUE_AS_MIX
|
||||
)
|
||||
|
|
@ -125,8 +130,8 @@ def two_dicts_to_string(headers, data, html_element='p'):
|
|||
(value, data.get(key, '')) for key, value in list(headers.items())
|
||||
]
|
||||
return "".join(
|
||||
["<{0}>{1}: {2}</{3}>".format(html_element, safe_text(key), \
|
||||
safe_text(value), html_element) \
|
||||
["<{0}>{1}: {2}</{3}>".format(html_element, safe_text(key),
|
||||
safe_text(value), html_element)
|
||||
for key, value in formatted_data]
|
||||
)
|
||||
|
||||
|
|
@ -295,7 +300,7 @@ def get_app_label_and_model_name(path):
|
|||
# *****************************************************************************
|
||||
# *****************************************************************************
|
||||
|
||||
def admin_change_url(app_label, module_name, object_id, extra_path='', \
|
||||
def admin_change_url(app_label, module_name, object_id, extra_path='',
|
||||
url_title=None):
|
||||
"""
|
||||
Gets an admin change URL for the object given.
|
||||
|
|
@ -309,7 +314,7 @@ def admin_change_url(app_label, module_name, object_id, extra_path='', \
|
|||
:return str:
|
||||
"""
|
||||
try:
|
||||
url = reverse('admin:{0}_{1}_change'.format(app_label, module_name), \
|
||||
url = reverse('admin:{0}_{1}_change'.format(app_label, module_name),
|
||||
args=[object_id]) + extra_path
|
||||
if url_title:
|
||||
return u'<a href="{0}">{1}</a>'.format(url, url_title)
|
||||
|
|
@ -370,48 +375,48 @@ def get_select_field_choices(raw_choices_data):
|
|||
|
||||
return choices
|
||||
|
||||
def validate_initial_for_choices(plugin_form, field_name_choices='choices', \
|
||||
def validate_initial_for_choices(plugin_form, field_name_choices='choices',
|
||||
field_name_initial='initial'):
|
||||
"""
|
||||
Validates the initial value for the choices given.
|
||||
|
||||
:param fobi.base.BaseFormFieldPluginForm plugin_form:
|
||||
"""
|
||||
availalble_choices = dict(
|
||||
available_choices = dict(
|
||||
get_select_field_choices(plugin_form.cleaned_data[field_name_choices])
|
||||
).keys()
|
||||
|
||||
if plugin_form.cleaned_data[field_name_initial] \
|
||||
and not plugin_form.cleaned_data[field_name_initial] \
|
||||
in availalble_choices:
|
||||
in available_choices:
|
||||
raise forms.ValidationError(
|
||||
_("Invalid value for initial: {0}. Should be any of the following"
|
||||
": {1}".format(plugin_form.cleaned_data[field_name_initial], \
|
||||
','.join(availalble_choices)))
|
||||
": {1}".format(plugin_form.cleaned_data[field_name_initial],
|
||||
','.join(available_choices)))
|
||||
)
|
||||
|
||||
return plugin_form.cleaned_data[field_name_initial]
|
||||
|
||||
def validate_initial_for_multiple_choices(plugin_form, \
|
||||
field_name_choices='choices', \
|
||||
def validate_initial_for_multiple_choices(plugin_form,
|
||||
field_name_choices='choices',
|
||||
field_name_initial='initial'):
|
||||
"""
|
||||
Validates the initial value for the multiple choices given.
|
||||
|
||||
:param fobi.base.BaseFormFieldPluginForm plugin_form:
|
||||
"""
|
||||
availalble_choices = dict(
|
||||
available_choices = dict(
|
||||
get_select_field_choices(plugin_form.cleaned_data[field_name_choices])
|
||||
).keys()
|
||||
|
||||
if plugin_form.cleaned_data[field_name_initial]:
|
||||
for choice in plugin_form.cleaned_data[field_name_initial].split(','):
|
||||
choice = choice.strip()
|
||||
if not choice in availalble_choices:
|
||||
if not choice in available_choices:
|
||||
raise forms.ValidationError(
|
||||
_("Invalid value for initial: {0}. Should be any "
|
||||
"of the following: {1}"
|
||||
"".format(choice, ','.join(availalble_choices)))
|
||||
"".format(choice, ','.join(available_choices)))
|
||||
)
|
||||
|
||||
return plugin_form.cleaned_data[field_name_initial]
|
||||
|
|
@ -422,10 +427,110 @@ def validate_submit_value_as(value):
|
|||
|
||||
:param str value:
|
||||
"""
|
||||
if not value in (SUBMIT_VALUE_AS_VAL, SUBMIT_VALUE_AS_REPR, \
|
||||
if not value in (SUBMIT_VALUE_AS_VAL, SUBMIT_VALUE_AS_REPR,
|
||||
SUBMIT_VALUE_AS_MIX):
|
||||
raise ImproperlyConfigured("The `SUBMIT_AS_VALUE` may have one of "
|
||||
"the following values: {0}, {1} or {2}"
|
||||
"".format(SUBMIT_VALUE_AS_VAL, \
|
||||
SUBMIT_VALUE_AS_REPR, \
|
||||
"".format(SUBMIT_VALUE_AS_VAL,
|
||||
SUBMIT_VALUE_AS_REPR,
|
||||
SUBMIT_VALUE_AS_MIX))
|
||||
|
||||
|
||||
class StrippedUser(object):
|
||||
"""
|
||||
Stripped user object.
|
||||
"""
|
||||
def __init__(self, user):
|
||||
"""
|
||||
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
self._user = user
|
||||
if not self._user.is_anonymous():
|
||||
setattr(self._user, User.USERNAME_FIELD, self._user.get_username())
|
||||
else:
|
||||
setattr(self._user, User.USERNAME_FIELD, None)
|
||||
|
||||
@property
|
||||
def email(self):
|
||||
return self._user.email
|
||||
|
||||
def get_username(self):
|
||||
"""
|
||||
"""
|
||||
return self._user.get_username()
|
||||
|
||||
def get_full_name(self):
|
||||
"""
|
||||
"""
|
||||
return self._user.get_full_name()
|
||||
|
||||
def get_short_name(self):
|
||||
"""
|
||||
"""
|
||||
return self._user.get_full_name()
|
||||
|
||||
def is_anonymous(self):
|
||||
return self._user.is_anonymous()
|
||||
|
||||
|
||||
class StrippedRequest(object):
|
||||
"""
|
||||
Stripped request object.
|
||||
"""
|
||||
def __init__(self, request):
|
||||
"""
|
||||
|
||||
:param django.http.HttpRequest request:
|
||||
:return:
|
||||
"""
|
||||
# Just to make sure nothing breaks if we don't provide the request
|
||||
# object, we do fall back to a fake request object.
|
||||
if request:
|
||||
self._request = request
|
||||
else:
|
||||
request_factory = RequestFactory()
|
||||
self._request = request_factory.get('/')
|
||||
|
||||
if hasattr(request, 'user') and request.user:
|
||||
self.user = StrippedUser(self._request.user)
|
||||
else:
|
||||
self.user = StrippedUser(AnonymousUser())
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""
|
||||
"""
|
||||
return self._request.path
|
||||
|
||||
@property
|
||||
def get_full_path(self):
|
||||
"""
|
||||
"""
|
||||
return self._request.get_full_path()
|
||||
|
||||
@property
|
||||
def is_secure(self):
|
||||
"""
|
||||
"""
|
||||
return self._request.is_secure()
|
||||
|
||||
@property
|
||||
def is_ajax(self):
|
||||
"""
|
||||
"""
|
||||
return self._request.is_ajax()
|
||||
|
||||
@property
|
||||
def META(self):
|
||||
"""
|
||||
"""
|
||||
META = {
|
||||
'HTTP_ACCEPT_ENCODING': self._request.META.get('HTTP_ACCEPT_ENCODING'),
|
||||
'HTTP_ACCEPT_LANGUAGE': self._request.META.get('HTTP_ACCEPT_LANGUAGE'),
|
||||
'HTTP_HOST': self._request.META.get('HTTP_HOST'),
|
||||
'HTTP_REFERER': self._request.META.get('HTTP_REFERER'),
|
||||
'HTTP_USER_AGENT': self._request.META.get('HTTP_USER_AGENT'),
|
||||
}
|
||||
return META
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ class IntegrationProcessor(object):
|
|||
# dynamically.
|
||||
FormClass = assemble_form_class(
|
||||
instance.form_entry,
|
||||
form_element_entries = form_element_entries
|
||||
form_element_entries = form_element_entries,
|
||||
request = request
|
||||
)
|
||||
|
||||
if 'POST' == request.method:
|
||||
|
|
|
|||
|
|
@ -76,9 +76,8 @@ class AbstractPluginModel(models.Model):
|
|||
#plugin_uid = models.CharField(_("Plugin UID"), max_length=255,
|
||||
# unique=True, editable=False)
|
||||
users = models.ManyToManyField(AUTH_USER_MODEL, verbose_name=_("User"),
|
||||
null=True, blank=True)
|
||||
groups = models.ManyToManyField(Group, verbose_name=_("Group"), null=True,
|
||||
blank=True)
|
||||
blank=True)
|
||||
groups = models.ManyToManyField(Group, verbose_name=_("Group"), blank=True)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
|
@ -138,7 +137,7 @@ class AbstractPluginModel(models.Model):
|
|||
|
||||
:return string:
|
||||
"""
|
||||
return ', '.join([u.username for u in self.users.all()])
|
||||
return ', '.join([u.get_username() for u in self.users.all()])
|
||||
users_list.allow_tags = True
|
||||
users_list.short_description = _('Users')
|
||||
|
||||
|
|
|
|||
|
|
@ -77,12 +77,15 @@ def get_or_create_admin_user():
|
|||
"""
|
||||
User = get_user_model()
|
||||
try:
|
||||
u = User._default_manager.get(username=FOBI_TEST_USER_USERNAME)
|
||||
kwargs = {
|
||||
User.USERNAME_FIELD: FOBI_TEST_USER_USERNAME,
|
||||
}
|
||||
u = User._default_manager.get(**kwargs)
|
||||
return u
|
||||
except ObjectDoesNotExist as e:
|
||||
|
||||
u = User()
|
||||
u.username = FOBI_TEST_USER_USERNAME
|
||||
setattr(u, User.USERNAME_FIELD, FOBI_TEST_USER_USERNAME)
|
||||
u.email = 'admin@dev.django-fobi.example.com'
|
||||
u.is_superuser = True
|
||||
u.is_staff = True
|
||||
|
|
|
|||
|
|
@ -332,15 +332,16 @@ def get_user_form_handler_plugin_uids(user):
|
|||
# ****************************************************************************
|
||||
# ****************************************************************************
|
||||
|
||||
def get_assembled_form(form_entry):
|
||||
def get_assembled_form(form_entry, request=None):
|
||||
"""
|
||||
Gets assembled form.
|
||||
|
||||
:param fobi.models.FormEntry form_entry:
|
||||
:param django.http.HttpRequest request:
|
||||
:return django.forms.Form:
|
||||
"""
|
||||
# TODO
|
||||
FormClass = assemble_form_class(form_entry)
|
||||
FormClass = assemble_form_class(form_entry, request=request)
|
||||
form = FormClass()
|
||||
return form
|
||||
|
||||
|
|
|
|||
|
|
@ -319,7 +319,8 @@ def edit_form_entry(request, form_entry_id, theme=None, template_name=None):
|
|||
FormClass = assemble_form_class(
|
||||
form_entry,
|
||||
origin = 'edit_form_entry',
|
||||
origin_kwargs_update_func = append_edit_and_delete_links_to_field
|
||||
origin_kwargs_update_func = append_edit_and_delete_links_to_field,
|
||||
request = request
|
||||
)
|
||||
|
||||
assembled_form = FormClass()
|
||||
|
|
@ -856,8 +857,11 @@ def view_form_entry(request, form_entry_slug, theme=None, template_name=None):
|
|||
|
||||
# This is where the most of the magic happens. Our form is being built
|
||||
# dynamically.
|
||||
FormClass = assemble_form_class(form_entry,
|
||||
form_element_entries=form_element_entries)
|
||||
FormClass = assemble_form_class(
|
||||
form_entry,
|
||||
form_element_entries = form_element_entries,
|
||||
request = request
|
||||
)
|
||||
|
||||
if 'POST' == request.method:
|
||||
form = FormClass(request.POST, request.FILES)
|
||||
|
|
|
|||
Loading…
Reference in a new issue