Planked code form betterforms. (Aka django 3.0 upgrade) (#436)
* Bump django from 2.2.8 to 3.0.2 in /src/requirements Bumps [django](https://github.com/django/django) from 2.2.8 to 3.0.2. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/2.2.8...3.0.2) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> * Planked code form betterforms. * Remove betterform from requirements. * Try with master of django-allauth-2fa. * Use static templatetag library, staticfiles is gone. * Use newly released django-allauth-2fa 0.8 instead of git url. * Django 3.0.3 is out. Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
This commit is contained in:
parent
baf43f0e22
commit
20f380dfd6
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load qrcode %}
|
||||
|
||||
{% block content %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% load bornhack %}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block extra_head %}
|
||||
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% load menubutton %}
|
||||
{% static "" as baseurl %}
|
||||
|
|
|
@ -59,7 +59,6 @@ INSTALLED_APPS = [
|
|||
"bootstrap3",
|
||||
"django_extensions",
|
||||
"reversion",
|
||||
"betterforms",
|
||||
]
|
||||
|
||||
# MEDIA_URL = '/media/'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load commonmark %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load imageutils %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load commonmark %}$
|
||||
|
||||
{% block title %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends 'profile_base.html' %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load commonmark %}$
|
||||
{% load token_tags %}
|
||||
|
||||
|
|
219
src/program/multiform.py
Normal file
219
src/program/multiform.py
Normal file
|
@ -0,0 +1,219 @@
|
|||
# Copied from https://github.com/fusionbox/django-betterforms/blob/master/betterforms/multiform.py
|
||||
|
||||
#
|
||||
# From https://github.com/fusionbox/django-betterforms/blob/master/LICENSE
|
||||
#
|
||||
# Copyright (c) 2013, Fusionbox, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# - Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from itertools import chain
|
||||
from functools import reduce
|
||||
from operator import add
|
||||
|
||||
from collections import OrderedDict
|
||||
from django.forms.utils import ErrorDict, ErrorList
|
||||
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
|
||||
class MultiForm(object):
|
||||
"""
|
||||
A container that allows you to treat multiple forms as one form. This is
|
||||
great for using more than one form on a page that share the same submit
|
||||
button. MultiForm imitates the Form API so that it is invisible to anybody
|
||||
else that you are using a MultiForm.
|
||||
"""
|
||||
form_classes = {}
|
||||
|
||||
def __init__(self, data=None, files=None, *args, **kwargs):
|
||||
# Some things, such as the WizardView expect these to exist.
|
||||
self.data, self.files = data, files
|
||||
kwargs.update(
|
||||
data=data,
|
||||
files=files,
|
||||
)
|
||||
|
||||
self.initials = kwargs.pop('initial', None)
|
||||
if self.initials is None:
|
||||
self.initials = {}
|
||||
self.forms = OrderedDict()
|
||||
self.crossform_errors = []
|
||||
|
||||
for key, form_class in self.form_classes.items():
|
||||
fargs, fkwargs = self.get_form_args_kwargs(key, args, kwargs)
|
||||
self.forms[key] = form_class(*fargs, **fkwargs)
|
||||
|
||||
def get_form_args_kwargs(self, key, args, kwargs):
|
||||
"""
|
||||
Returns the args and kwargs for initializing one of our form children.
|
||||
"""
|
||||
fkwargs = kwargs.copy()
|
||||
prefix = kwargs.get('prefix')
|
||||
if prefix is None:
|
||||
prefix = key
|
||||
else:
|
||||
prefix = '{0}__{1}'.format(key, prefix)
|
||||
fkwargs.update(
|
||||
initial=self.initials.get(key),
|
||||
prefix=prefix,
|
||||
)
|
||||
return args, fkwargs
|
||||
|
||||
def __str__(self):
|
||||
return self.as_table()
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.forms[key]
|
||||
|
||||
@property
|
||||
def errors(self):
|
||||
errors = {}
|
||||
for form_name in self.forms:
|
||||
form = self.forms[form_name]
|
||||
for field_name in form.errors:
|
||||
errors[form.add_prefix(field_name)] = form.errors[field_name]
|
||||
if self.crossform_errors:
|
||||
errors[NON_FIELD_ERRORS] = self.crossform_errors
|
||||
return errors
|
||||
|
||||
@property
|
||||
def fields(self):
|
||||
fields = []
|
||||
for form_name in self.forms:
|
||||
form = self.forms[form_name]
|
||||
for field_name in form.fields:
|
||||
fields += [form.add_prefix(field_name)]
|
||||
return fields
|
||||
|
||||
def __iter__(self):
|
||||
# TODO: Should the order of the fields be controllable from here?
|
||||
return chain.from_iterable(self.forms.values())
|
||||
|
||||
@property
|
||||
def is_bound(self):
|
||||
return any(form.is_bound for form in self.forms.values())
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
Raises any ValidationErrors required for cross form validation. Should
|
||||
return a dict of cleaned_data objects for any forms whose data should
|
||||
be overridden.
|
||||
"""
|
||||
return self.cleaned_data
|
||||
|
||||
def add_crossform_error(self, e):
|
||||
self.crossform_errors.append(e)
|
||||
|
||||
def is_valid(self):
|
||||
forms_valid = all(form.is_valid() for form in self.forms.values())
|
||||
try:
|
||||
self.cleaned_data = self.clean()
|
||||
except ValidationError as e:
|
||||
self.add_crossform_error(e)
|
||||
return forms_valid and not self.crossform_errors
|
||||
|
||||
def non_field_errors(self):
|
||||
form_errors = (
|
||||
form.non_field_errors() for form in self.forms.values()
|
||||
if hasattr(form, 'non_field_errors')
|
||||
)
|
||||
return ErrorList(chain(self.crossform_errors, *form_errors))
|
||||
|
||||
def as_table(self):
|
||||
return mark_safe(''.join(form.as_table() for form in self.forms.values()))
|
||||
|
||||
def as_ul(self):
|
||||
return mark_safe(''.join(form.as_ul() for form in self.forms.values()))
|
||||
|
||||
def as_p(self):
|
||||
return mark_safe(''.join(form.as_p() for form in self.forms.values()))
|
||||
|
||||
def is_multipart(self):
|
||||
return any(form.is_multipart() for form in self.forms.values())
|
||||
|
||||
@property
|
||||
def media(self):
|
||||
return reduce(add, (form.media for form in self.forms.values()))
|
||||
|
||||
def hidden_fields(self):
|
||||
# copy implementation instead of delegating in case we ever
|
||||
# want to override the field ordering.
|
||||
return [field for field in self if field.is_hidden]
|
||||
|
||||
def visible_fields(self):
|
||||
return [field for field in self if not field.is_hidden]
|
||||
|
||||
@property
|
||||
def cleaned_data(self):
|
||||
return OrderedDict(
|
||||
(key, form.cleaned_data)
|
||||
for key, form in self.forms.items() if form.is_valid()
|
||||
)
|
||||
|
||||
@cleaned_data.setter
|
||||
def cleaned_data(self, data):
|
||||
for key, value in data.items():
|
||||
child_form = self[key]
|
||||
if hasattr(child_form, 'forms'):
|
||||
for formlet, formlet_data in zip(child_form.forms, value):
|
||||
formlet.cleaned_data = formlet_data
|
||||
else:
|
||||
child_form.cleaned_data = value
|
||||
|
||||
|
||||
class MultiModelForm(MultiForm):
|
||||
"""
|
||||
MultiModelForm adds ModelForm support on top of MultiForm. That simply
|
||||
means that it includes support for the instance parameter in initialization
|
||||
and adds a save method.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.instances = kwargs.pop('instance', None)
|
||||
if self.instances is None:
|
||||
self.instances = {}
|
||||
super(MultiModelForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_form_args_kwargs(self, key, args, kwargs):
|
||||
fargs, fkwargs = super(MultiModelForm, self).get_form_args_kwargs(key, args, kwargs)
|
||||
try:
|
||||
# If we only pass instance when there was one specified, we make it
|
||||
# possible to use non-ModelForms together with ModelForms.
|
||||
fkwargs['instance'] = self.instances[key]
|
||||
except KeyError:
|
||||
pass
|
||||
return fargs, fkwargs
|
||||
|
||||
def save(self, commit=True):
|
||||
objects = OrderedDict(
|
||||
(key, form.save(commit))
|
||||
for key, form in self.forms.items()
|
||||
)
|
||||
|
||||
if any(hasattr(form, 'save_m2m') for form in self.forms.values()):
|
||||
def save_m2m():
|
||||
for form in self.forms.values():
|
||||
if hasattr(form, 'save_m2m'):
|
||||
form.save_m2m()
|
||||
self.save_m2m = save_m2m
|
||||
|
||||
return objects
|
|
@ -13,7 +13,6 @@ from django.urls import reverse, reverse_lazy
|
|||
from django.template import Engine, Context
|
||||
from django.shortcuts import redirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from betterforms.multiform import MultiModelForm
|
||||
import icalendar
|
||||
|
||||
from camps.mixins import CampViewMixin
|
||||
|
@ -31,6 +30,7 @@ from .email import (
|
|||
add_eventproposal_updated_email,
|
||||
)
|
||||
from . import models
|
||||
from .multiform import MultiModelForm
|
||||
from .forms import SpeakerProposalForm, EventProposalForm
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
Django==2.2.9 # 3.0 is waiting for https://github.com/bornhack/bornhack-website/issues/435
|
||||
Django==3.0.3
|
||||
channels==2.4.0
|
||||
channels-redis==2.4.1
|
||||
|
||||
|
||||
asyncio==3.4.3
|
||||
commonmark==0.9.1
|
||||
django-allauth-2fa==0.7
|
||||
django-betterforms==1.2
|
||||
django-allauth-2fa==0.8
|
||||
django-bleach==0.6.1
|
||||
django-bootstrap3==12.0.3
|
||||
django-cors-headers==3.2.1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load shop_tags %}
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load shop_tags %}
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load shop_tags %}
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load shop_tags %}
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load commonmark %}
|
||||
|
||||
{% block title %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% load menubutton %}
|
||||
{% static "" as baseurl %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<table style="width:100%;">
|
||||
<tr>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static from staticfiles %}
|
||||
{% load static %}
|
||||
{% load commonmark %}$
|
||||
|
||||
{% block title %}
|
||||
|
|
Loading…
Reference in a new issue