def test_errors_rendering(): form = Form(errors__attrs__foo='foo').bind(request=req('get')) form.add_error('foo') form.add_error('bar') assert form.errors assert form.errors.__html__( ) == '<ul foo="foo"><li>bar</li><li>foo</li></ul>'
class MyPage(Page): header = Fragment() some_form = Form(fields=Namespace(fisk=Field(), )) some_other_form = Form(fields=Namespace( fjomp=Field(), fisk=Field(), )) a_table = Table( model=TFoo, columns=Namespace( columns=Column(), fusk=Column(attr='b', filter__include=True), ), )
def edit(request, short): return Form.edit(auto__instance=Entry.objects.get(short=short), fields=dict( creator__editable=False, use_count__editable=False, created_at__editable=False, ))
def test_from_model_missing_subfield(): with pytest.raises(Exception) as e: Form( auto__model=SomeModel, auto__include=['foo__barf'], ) assert str(e.value) == '''\
def test_ajax_not_trigger_bind(): p = Page( parts=dict( form=Form( endpoints__foo__func=lambda value, **_: HttpResponse('bar'), ), exploding_form=ExplodingForm(), ) ) p = p.bind( request=req( 'get', **{ '/foo': '', }, ) ) assert p.render_to_response().content == b'bar' with pytest.raises(Exception) as e: # noinspection PyStatementEffect p.parts.exploding_form assert str(e.value) == 'Boom'
def test_post_not_trigger_bind(): p = Page( parts=dict( form=Form( fields__foo=Field(), ), exploding_form=ExplodingForm(), ) ) p = p.bind( request=req( 'post', **{ '-': '', 'foo': 'bar', }, ) ) assert p.parts.form.fields.foo.value == 'bar' with pytest.raises(Exception) as e: # noinspection PyStatementEffect p.parts.exploding_form assert str(e.value) == 'Boom'
def form_example_children_that_are_not_fields(request): def on_submit(form, **_): if not form.is_valid(): return return html.pre(f"You posted: {form.apply(Struct())}").bind(request=request) def post_validation(form, **_): if form.is_valid(): if form.fields.f1.value + form.fields.f2.value != form.fields.f3.value: form.add_error("Calculate again!") return Form( iommi_style="bulma", title="Children that are not fields", fields__name=Field(), fields__color=Field.choice(choices=['Red', 'Green', 'Blue']), fields__in_box=html.div( children__f1=Field.integer(attrs__class__column=True), children__plus=html.span("+", attrs__class={'column': True, 'is-narrow': True}), children__f2=Field.integer(attrs__class__column=True,), children__equals=html.span("=", attrs__class={'column': True, 'is-narrow': True}), children__f3=Field.integer(attrs__class_column=True), iommi_style="bulma_query_form", attrs__class={'box': True, 'columns': True, 'is-vcentered': True} ), post_validation=post_validation, actions__submit__post_handler=on_submit )
def edit(request, context_name, document_name): doc = Document.objects.get(context__name__iexact=context_name, name__iexact=document_name) document_version = doc.versions.all().order_by('-pk')[0] # TODO: # - on save, validate that no one has edited in the meantime return Form.create( auto__model=DocumentVersion, auto__exclude=['changed_time'], title=f'Edit {doc}', fields=dict( document=dict( initial=doc, editable=False, call_target__attribute='hidden', ), name__initial=document_version.name, content=dict( initial=document_version.content, attrs__style=dict( height='40rem', width='50rem', ), ), custom_data__initial=document_version.custom_data, version=dict( initial=document_version.version + 1, editable=False, call_target=Field.hidden, ), ), actions__submit__display_name='Save', )
def test_include_not_existing_error(): with pytest.raises(AssertionError) as e: Form( auto__model=FormFromModelTest, auto__include=['does_not_exist'], ) assert str(e.value) == 'You can only include fields that exist on the model: does_not_exist specified but does not exist\nExisting fields:\n f_bool\n f_file\n f_float\n f_int\n f_int_excluded\n id'
def test_exclude(): f = Form( auto__model=FormFromModelTest, auto__exclude=[ 'f_bool', 'f_int', ], ) assert list(f._declared_members.fields.keys()) == ['id', 'f_float', 'f_file', 'f_int_excluded']
def form_example_6(request): return Form.edit(auto__instance=Artist.objects.all().first(), actions=dict( foo=Action.submit(attrs__value='Foo'), bar=Action.submit(attrs__value='Bar'), a=Action.submit(attrs__value='Foo', group='x'), b=Action.submit(attrs__value='Bar', group='x'), back=Action(display_name='Back to index', attrs__href='/'), ))
class BusyPage(Page): tfoo = Table(auto__model=TFoo, page_size=5, columns__name__filter=dict(include=True, field__include=True)) tbar = Table(auto__model=TBar, page_size=5, columns__b__filter=dict(include=True, field__include=True)) create_tbar = Form.create(auto__model=TBar)
def test_from_model(): f = Form( auto__model=SomeModel, auto__include=['foo__bar'], ) declared_fields = f._declared_members.fields assert list(declared_fields.keys()) == ['foo_bar'] assert declared_fields['foo_bar'].attr == 'foo__bar'
def create(request): return Form.create(auto__model=Entry, fields=dict( creator__initial=request.user, use_count__include=False, approver__include=False, created_at=dict(editable=False, initial=datetime.now()), valid_to__initial=timezone.now() + timedelta(days=30), ))
def test_respect_include_ordering(): include = [ 'f_bool', 'f_float', 'f_file', 'f_int', ] f = Form( auto__model=FormFromModelTest, auto__include=include, ) assert list(f._declared_members.fields.keys()) == include
def test_from_model_missing_subfield(): with pytest.raises(Exception) as e: Form( auto__model=SomeModel, auto__include=['foo__barf'], ) assert (str(e.value) == '''\ You can only include fields that exist on the model: foo__barf specified but does not exist Existing fields: foo__bar foo__id foo__pk foo__somemodel''')
def form_example_error_messages(request): def form_error_messages(form, **_): form.add_error(gettext('Global error message 1')) form.add_error(gettext('Global error message 2')) def field_error_messages(field, **_): field.add_error(gettext('Field error message 1')) field.add_error(gettext('Field error message 2')) return Form(title=gettext('Error messages'), auto__model=Artist, post_validation=form_error_messages, fields__name__post_validation=field_error_messages)
def vote(request, question_id): # question = get_object_or_404(Question, pk=question_id) # try: # selected_choice = question.choice_set.get(pk=request.POST['choice']) # except (KeyError, Choice.DoesNotExist): # # Redisplay the question voting form. # return render(request, 'polls/detail.html', { # 'question': question, # 'error_message': "You didn't select a choice.", # }) # else: # selected_choice.votes += 1 # selected_choice.save() # # Always return an HttpResponseRedirect after successfully dealing # # with POST data. This prevents data from being posted twice if a # # user hits the Back button. # return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) # <h1>{{ question.question_text }}</h1> # # {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} # # <form action="{% url 'polls:vote' question.id %}" method="post"> # {% csrf_token %} # {% for choice in question.choice_set.all %} # <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"> # <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br> # {% endfor %} # <input type="submit" value="Vote"> # </form> question = get_object_or_404(Question, pk=question_id) def post_handler(form, **_): if form.is_valid(): choice = form.fields.choice.value choice.votes += 1 choice.save() return HttpResponseRedirect( reverse('polls:results', args=(question.id, ))) return Form( title=str(question), fields__choice=Field.choice_queryset(question.choice_set.all()), actions__submit__post_handler=post_handler, )
def create_issue(request, project_name): project = Project.objects.get(name=project_name) def post_handler(form, **kwargs): result = create_object__post_handler(form=form, **kwargs) if form.is_valid(): form.instance.comments = Room.objects.create( name=f'Issue comments {project}/{form.instance}', custom_data=f'issues/{project.pk}/{form.instance.pk}') form.instance.save() return result return Form.create( auto__model=Issue, auto__exclude=['time_created', 'last_changed_time', 'comments'], fields__project=Field.hidden(editable=False, initial=project), fields__last_changed_by=Field.hidden(editable=False, initial=request.user), actions__submit__post_handler=post_handler, )
def detail(request, question_id): # question = get_object_or_404(Question, pk=question_id) # return render(request, 'polls/detail.html', {'question': question}) # OR # class DetailView(generic.DetailView): # model = Question # template_name = 'polls/detail.html' # <h1>{{ question.question_text }}</h1> # <ul> # {% for choice in question.choice_set.all %} # <li>{{ choice.choice_text }}</li> # {% endfor %} # </ul> return Form( auto__instance=get_object_or_404(Question, pk=question_id), editable=False, )
def delete_album(request, artist, album): album = get_object_or_404(Album, name=album, artist__name=artist) return Form.delete(auto__instance=album)
def edit_album(request, artist, album): album = get_object_or_404(Album, name=album, artist__name=artist) return Form.edit(auto__instance=album) def delete_album(request, artist, album): album = get_object_or_404(Album, name=album, artist__name=artist) return Form.delete(auto__instance=album) # URLs ----------------------------- urlpatterns = [ path('', IndexPage().as_view()), path( 'albums/', AlbumTable(auto__model=Album, columns__year__bulk__include=True).as_view()), path('albums/create/', Form.create(auto__model=Album).as_view()), path('artists/', ArtistTable(auto__model=Artist).as_view()), path('tracks/', TrackTable(auto__model=Track).as_view()), path('artist/<artist>/', artist_page), path('artist/<artist>/<album>/', album_page), path('artist/<artist>/<album>/edit/', edit_album), path('artist/<artist>/<album>/delete/', delete_album), ]
def edit_album(request, artist, album): album = get_object_or_404(Album, name=album, artist__name=artist) return Form.edit(auto__instance=album)
def test_errors_rendering_template(): form = Form(errors__template=Template('foo')).bind(request=req('get')) form.add_error('foo') form.add_error('bar') assert form.errors assert form.errors.__html__() == 'foo'
def test_get_wrapped_view_function(): assert get_wrapped_view(view) is view assert get_wrapped_view(csrf_exempt(view)) is view get_wrapped_view(Form.create(auto__model=TFoo).as_view())
from django.urls import path from iommi import Form from . import views from .models import ( Project, ) urlpatterns = [ path('', views.view_project_list), path('create/', Form.create(auto__model=Project).as_view()), path('projects/<str:project_name>/', views.view_project), path('projects/<str:project_name>/create/', views.create_issue), path('projects/<str:project_name>/issues/<int:issue_pk>/', views.view_issue), ]
Table, Form, ) from examples.models import ( TFoo, Foo, ) from iommi.admin import Admin urlpatterns = [ path('', views.index, name='index'), path('form_example_1/', views.form_example_1, name='example_1'), path('form_example_2/', views.form_example_2, name='example_2'), path('form_example_2b/', Form.create(auto__model=Foo).as_view(), name='example_2b'), path('form_example_3/', views.form_example_3, name='example_3'), path('form_example_4/', views.form_example_4, name='example_4'), path('form_example_5/', views.form_example_5, name='example_5'), path('form_kitchen/', views.form_kitchen), path('table_readme_example_1/', views.table_readme_example_1, name='readme_example_1'), path('table_readme_example_2/', views.table_readme_example_2, name='readme_example_2'), path('table_auto_example_1/', views.table_auto_example_1, name='readme_example_1'), path('table_auto_example_2/', views.table_auto_example_2, name='readme_example_2'), path('table_kitchen_sink/', views.table_kitchen_sink, name='kitchen_sink'), path('table_as_view/', Table( auto__model=TFoo, columns__a__bulk__include=True, bulk__actions__delete__include=True, extra_evaluated__report_name='example_download',
def delete(request, short): return Form.delete(auto__instance=Entry.objects.get(short=short), )
def form_example_4(request): return Form.create(auto__model=Artist)
def form_example_5(request): return Form.edit(auto__instance=Artist.objects.all().first())