Skip to content

Commit

Permalink
Merge 19d4695 into 8da378d
Browse files Browse the repository at this point in the history
  • Loading branch information
AltusBarry committed Aug 6, 2019
2 parents 8da378d + 19d4695 commit 140e09d
Show file tree
Hide file tree
Showing 19 changed files with 187 additions and 141 deletions.
37 changes: 30 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
language: python

matrix:
include:
- python: 2.7
env: TOXENV=django110
- python: 2.7
env: TOXENV=django111
- python: 3.5
env: TOXENV=django2
include:
- python: "2.7"
env: TOXENV=django111-py27

- python: "3.5"
env: TOXENV=django111-py35
- python: "3.5"
env: TOXENV=django21-py35
- python: "3.5"
env: TOXENV=django22-py35

- python: "3.6"
env: TOXENV=django111-py36
- python: "3.6"
env: TOXENV=django21-py36
- python: "3.6"
env: TOXENV=django22-py36

- python: "3.7"
sudo: required
dist: xenial
env: TOXENV=django111-py37
- python: "3.7"
sudo: required
dist: xenial
env: TOXENV=django21-py37
- python: "3.7"
sudo: required
dist: xenial
env: TOXENV=django22-py37

install:
- pip install tox
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Changelog

next
----
#. Django 2.0 and Python 3.5 support.
#. Added Django 2.1 and 2.2 along with Python 3.5, 3.6, 3.7 support.
#. Remove Django 1.10 support.
#. Added helper method on Form model that returns the form's kwargs.

0.2.3
-----
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ Settings

FORMFACTORY["field-types"]
Control the form fields types that can be selected in Admin.
Supports adding none Django fields: ``("<module_for_field>", "<display_name>")``
Supports adding non Django fields: ``("<module_for_field>", "<display_name>")``
eg. ``("formfactory.fields.ParagraphField", "ParagraphField")``

FORMFACTORY["widget-types"]
Control the form widget types that can be selected in Admin.
Supports adding none Django widgets: ``("<module_for_widget>", "<display_name>")``
Supports adding non Django widgets: ``("<module_for_widget>", "<display_name>")``
eg. ``("formfactory.widgets.ParagraphWidget", "ParagraphWidget")``

Widgets and Fields
Expand Down
30 changes: 27 additions & 3 deletions formfactory/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@
from formfactory import SETTINGS, utils


# TODO: Document filter_fields and order_fieldgroup_fields
class FormFactory(forms.Form):
"""Builds a form class from defined fields passed to it by the Form model.
"""

# TODO: Update uuid in __init__. Forms are readied up during django
# startup, meaning the uuid is only set once and not updated for each form
# instance.
uuid = forms.UUIDField(
initial=str(uuid4()), widget=forms.HiddenInput
)
Expand All @@ -42,11 +47,16 @@ def __init__(self, *args, **kwargs):

# Models aren't ready when the file is initially processed.
from formfactory import models
field_through = models.FieldGroupThrough

# TODO: Duplicate field groups and fields allowed. Has possible
# unintended side effect that only the last field value is ever stored
# using the default store data action.
for field_group in defined_field_groups:

fields = utils.order_by_through(
field_group.fields.all(),
fields = self.filter_fields(field_group)

fields = self.order_fieldgroup_fields(
fields,
"FieldGroupThrough",
"field_group",
field_group,
Expand Down Expand Up @@ -151,6 +161,20 @@ def __init__(self, *args, **kwargs):
if choices:
self.fields[field.slug].widget.choices = choices

def filter_fields(self, field_group):
"""Customisable method that allows for the overriding of the default
field queryset for each field group.
"""
return field_group.fields.all()

# TODO: Django Form class already has a order_fields method. Look into
# using that.
def order_fieldgroup_fields(self, fields, *args):
"""Customisable method that allows for the customisation of the field
order.
"""
return utils.order_by_through(fields, *args)

def _html_output(self, normal_row, error_row, row_ender, help_text_html,
errors_on_separate_row):
"""Helper function for outputting HTML. Used by as_table(), as_ul(),
Expand Down
7 changes: 6 additions & 1 deletion formfactory/fields.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import markdown

import django
from django.forms.fields import Field
from django.utils.text import mark_safe
from django.utils.translation import ugettext as _

if django.VERSION[0] < 2:
from django.utils.text import mark_safe
else:
from django.utils.safestring import mark_safe

from formfactory import widgets


Expand Down
77 changes: 65 additions & 12 deletions formfactory/models.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import importlib
import markdown

import django
from django import forms
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.urls import reverse
from django.utils.text import mark_safe
from django.utils.translation import ugettext as _

if django.VERSION[0] < 2:
from django.utils.text import mark_safe
else:
from django.utils.safestring import mark_safe


from simplemde.fields import SimpleMDEField

from formfactory import (
_registry, actions, clean_methods, factory, SETTINGS, validators, utils
SETTINGS,
_registry,
actions,
clean_methods,
factory,
utils,
validators,
)


Expand All @@ -29,8 +41,10 @@ def _FIELD_TYPES():
fields = fields + ((content_type, field),)
return fields


FIELD_TYPES = _FIELD_TYPES()


def _WIDGET_TYPES():
widgets = ()
for content_type, widget in SETTINGS["widget-types"]:
Expand All @@ -39,6 +53,7 @@ def _WIDGET_TYPES():
widgets = widgets + ((content_type, widget),)
return widgets


WIDGET_TYPES = _WIDGET_TYPES()

ERROR_MESSAGES = tuple(
Expand Down Expand Up @@ -71,6 +86,8 @@ class Meta(object):
def __unicode__(self):
return "%s (%s)" % (self.form.title, self.uuid)

__str__ = __unicode__


class FormDataItem(models.Model):
"""A basic store for form data items.
Expand All @@ -90,6 +107,8 @@ class Action(models.Model):
def __unicode__(self):
return self.action

__str__ = __unicode__

@property
def as_function(self):
return _registry["actions"][self.action]
Expand All @@ -103,6 +122,8 @@ class Validator(models.Model):
def __unicode__(self):
return self.validator

__str__ = __unicode__

@property
def as_function(self):
return _registry["validators"][self.validator]
Expand All @@ -116,6 +137,8 @@ class CleanMethod(models.Model):
def __unicode__(self):
return self.clean_method

__str__ = __unicode__

@property
def as_function(self):
return _registry["clean_methods"][self.clean_method]
Expand All @@ -132,6 +155,8 @@ class Meta(object):
def __unicode__(self):
return "%s: %s" % (self.key, self.value)

__str__ = __unicode__


class ActionParam(models.Model):
"""Defines a constant that can be passed to the action function.
Expand All @@ -145,6 +170,8 @@ class ActionParam(models.Model):
def __unicode__(self):
return "%s:%s" % (self.key, self.value)

__str__ = __unicode__


class FormActionThrough(models.Model):
"""Through table for form actions which defines an order.
Expand All @@ -161,6 +188,8 @@ class Meta(object):
def __unicode__(self):
return "%s (%s)" % (self.action.action, self.order)

__str__ = __unicode__


class BaseFormModel(models.Model):
"""Form model which encompasses a set of form fields and defines an action
Expand Down Expand Up @@ -214,6 +243,8 @@ class Meta(object):
def __unicode__(self):
return self.title

__str__ = __unicode__

def get_absolute_url(self):
if self.enable_csrf:
return reverse(
Expand All @@ -228,15 +259,7 @@ def get_absolute_url(self):
def absolute_url(self):
return self.get_absolute_url()

def as_form(self, **kwargs):
"""
Builds the form factory object and returns it.
"""
if not self.pk:
raise AttributeError(
"The model needs to be saved before a form can be generated."
)

def get_form_kwargs(self, **kwargs):
ordered_field_groups = utils.order_by_through(
self.fieldgroups.all(),
"FieldGroupFormThrough",
Expand All @@ -251,8 +274,18 @@ def as_form(self, **kwargs):
"prefix": kwargs.get("prefix", self.slug),
"clean_method": self.clean_method
})
return kwargs

def as_form(self, **kwargs):
"""
Builds the form factory object and returns it.
"""
if not self.pk:
raise AttributeError(
"The model needs to be saved before a form can be generated."
)

return factory.FormFactory(**kwargs)
return factory.FormFactory(**self.get_form_kwargs(**kwargs))


class Wizard(BaseFormModel):
Expand All @@ -265,6 +298,8 @@ class Wizard(BaseFormModel):
def __unicode__(self):
return self.title

__str__ = __unicode__

def absolute_url(self):
return self.get_absolute_url()

Expand All @@ -287,6 +322,8 @@ class Meta(object):
def __unicode__(self):
return "%s (%s)" % (self.form.title, self.order)

__str__ = __unicode__


class WizardActionThrough(models.Model):
"""Through table for wizard actions with a defined order.
Expand All @@ -303,6 +340,8 @@ class Meta(object):
def __unicode__(self):
return "%s (%s)" % (self.action.action, self.order)

__str__ = __unicode__


class FieldChoice(models.Model):
"""Defines options for select or multiselect field types.
Expand All @@ -316,6 +355,8 @@ class Meta(object):
def __unicode__(self):
return "%s:%s" % (self.label, self.value)

__str__ = __unicode__


class FormFieldGroup(models.Model):
"""Enable the grouping of fields and how that field should be rendered.
Expand All @@ -334,6 +375,8 @@ class FormFieldGroup(models.Model):
def __unicode__(self):
return self.title

__str__ = __unicode__


class FieldGroupFormThrough(models.Model):
"""Through table for field groups forms with a defined order.
Expand All @@ -350,6 +393,8 @@ class Meta(object):
def __unicode__(self):
return "%s (%s)" % (self.field_group.title, self.order)

__str__ = __unicode__


class FormField(models.Model):
"""Defines a form field with all options and required attributes.
Expand Down Expand Up @@ -399,6 +444,8 @@ class FormField(models.Model):
def __unicode__(self):
return self.title

__str__ = __unicode__

@property
def get_field_meta(self):
"""
Expand Down Expand Up @@ -452,6 +499,8 @@ class Meta(object):
def __unicode__(self):
return "%s (%s)" % (self.field.title, self.order)

__str__ = __unicode__


class FormFieldErrorMessageProxy(FormField.error_messages.through):
class Meta:
Expand All @@ -461,6 +510,8 @@ class Meta:
def __unicode__(self):
return str(self.customerrormessage)

__str__ = __unicode__


class FormFieldValidatorProxy(FormField.additional_validators.through):
class Meta:
Expand All @@ -469,3 +520,5 @@ class Meta:

def __unicode__(self):
return str(self.validator)

__str__ = __unicode__
5 changes: 0 additions & 5 deletions formfactory/tests/requirements/110.txt

This file was deleted.

Loading

0 comments on commit 140e09d

Please sign in to comment.