I am new to Django and tried making a view that holds a list of forms and handles them. I am familiar with the FormView provided by django's generic views however it only holds one form in it.
The idea is that the main form I have is split into a few forms, and then the "mini-forms" are held in a list ("forms").
Since I'm splitting the form into parts and saving a list of forms (for reasons like re-usability and such), the template looks something like this (which does the trick):
...
<form ...>
{% for form in forms %}
{{ form.as_p }}
{% endfor %}
<input type="submit"...>
</form>
...
I have been messing around with the view that should handle the forms, validate them and will get the data from them. Since I feel like Im making it more complicated than it should really be, I'd like to ask you to give an example of a simple view for that, that Ill develop further (get
This may be more a comment but I don't have quite enough rep to respond as a comment so I'm putting this in an answer:
If your primary concern is reusability have you considered creating Mixins instead of making a list of forms?
an example of this could be:
from django import forms
class NameFormMixin(object):
your_name = forms.CharField(label='Your name')
class EmailFormMixin(object):
email = forms.EmailField(label='Your Email')
class NameEmailForm(forms.Form,
NameFormMixin,
EmailFormMixin):
pass
you could include your validation functions in the mixins and have general django form functions in the main form class.
Related
I have been working a lot with Django's template language lately, and it works well in most cases, but recently I've come across a small problem it hasn't been able to solve.
I'm iterating over a bunch of database objects, and building a button in the template from each of them. Something like this:
{% for item in items %}
<button id="{{ item.action.id }}">
{{ item.action.text }}
</button>
{% endfor %}
This works fine, but my Action class is inheritable, and may have a different button structure. Say I wanted to sometimes have a javascript function attached as well. My first though was well, let's just create a render method in my class, and then call that in my template.
class ScriptAction(Action):
def render(self):
return '''
<button id="{}" onclick={}>
{}
</button>'''.format(self.id, self.func, self.text)
Because no the template is much more elegant, and doesn't rely on a fixed button structure:
{% for item in items %}
{{ item.action.render|safe }}
{% endfor %}
And now for my actual problem: what if this rendered string needs further processing by django?
Maybe render method returns a string like
<button id="action-button-id" onclick="console.log('clicked')">
{{ item.name }}
</button>
Currently, {{ item.name }} will not be rendered in the template loop. Is there a way of getting around this?
Perhaps I making this more complicated than it should be, but I've looked through the Django built-in tags and filters, even looked at writing you own parser. But at this point something inside me told me that I was being obsessive. This is actually just a small problem, and would require a fair amount of time, so -
is this more effort than it is worth?
is writing complex parsers like this secure?
is the Django template language even able to do something like this?
If you could hone in on some of these points, I would really appreciate it. This problem is really bugging me.
Thanks in advance!
I'd look into the simple_tag option for building a custom template tag, and have the tag:
Take the model instance as its argument (plus context!)
Ask the model instance for a snippet of template code to use in rendering it
Use the raw template API to render that template snippet
Return the result, optionally marked safe if you know it is safe.
In templates you can write forms in several ways: either by an already created Django form or by a plain html form. Both of them are okay, and can be used, so I am interested in case of using each form. I've used ModelForm several times and it's a really nice shortcut, also I am reading a Django book and Django forms are introduced as a good way of validation, even if you won't use them in your templates. But also many tutorials show html forms where a django froms are expected (at least for me). An example in a search form. All of the tutorials I've seen use plain html form, capture a query and return a queryset. Why wouldn't they write a separate form and use it as {{ SearchForm }}?
Personally, I never use {{ form.field }} syntax in my templates. I always write HTML for my forms. Because it is easy to assign classes, ids and other data attributes to form inputs in HTML rather than doing the same in forms.py
When you need to assign classes and ids to form inputs, you will need to do something like this:
myfield = forms.CharField(
widget=forms.TextArea(
attrs={'class': 'some-class',
'id': 'SomeId',
'rows': '10',
'style': 'margin-top: 10px;',
}
)
)
Frankly, it sucks. Now compare the above code with this:
<textarea name="myfield" rows="10" class="some-class" id="SomeId" style="margin-top: 10px;"></textarea>
And now your Django code can get a little shorter, thereby cleaner:
myfield = forms.CharField()
The HTML syntax is far better than corresponding Python syntax. It feels more natural. Also, if you've got a designer working with you on a project who doesn't know Python, this way you both won't interfere with each other's development process.
So I have my django project which includes a HTML page that shows a list and a submit button.
I want to use the submit button to send the selected item ID to the server and than use it.
That`s my code :
<form>
<select>
{% for item in list %}
<option value={{item.name}}>{{ item.name }}</option>
{% endfor %}
</select>
<input type="submit"/>
</form>
The things I want to know are :
What to write in the action of the form so it will only reload the page.
How to enter the form data into a view.
As i understand, you want to take the value on your select and do something with it in the server.
I would advise you to read the documentation, as it is pretty detailed about what you need to know to work with forms. You should also read a little about forms, as you are missing a couple details.
Now, the action must point to one of your urls. Your url must be pointing to a view and in your view, if everything is ok, you should be getting a request object.
Depending on your post method, you have a python dictionary in request.GET or request.POST, filled with the values in your form.
That is assuming you are using your form created from scratch. In django you can use the Form class, which creates the html (or lets you create it, but giving you some constraints), validates the form, saves the form to a model (in the case it is a ModelForm). It is a valuable class for me and prefer it over working with raw html.
Also, assuming you haven't, i strongly advice you to go through the getting started. Even if it keeps things basic, it does a good job at introducing core django modules.
Are there any real reason to use builtin forms in django?
One of them as I understand is validation. Ok. And maybe some convinience (but not for me).
Anything else?
Is there any acceleration in site work with forms?
From Django documentation -
While it is possible to process form submissions just using Django’s
HttpRequest class, using the form library takes care of a number of
common form-related tasks. Using it, you can:
Display an HTML form with automatically generated form widgets.
Check submitted data against a set of validation rules.
Redisplay a form in the case of validation errors.
Convert submitted form data to the relevant Python data types.
Also django forms provide some level of security by enforcing CSRF.
Some of the cool things you can do with django forms
I agree that in some circumstances, the temptation to avoid the use of Django form is very strong.
If I need just one field with no validation nor style, why should I define a django-form?
HTML:
<form method='POST' action='url_to_my_view'>
Type something: <input type='text' name='any_value'/>
</form>
Django:
<form method='POST' action='url_to_my_view'>
{{ form }}
</form>
with the overhead of defining the form and including it in the view.
But I still use Django-forms: experience tells me that software shortcuts always lead to problems...
The more built-in forms, the less work for developers. You are free to implement them from 0 but it is always faster to use something that is already done and tested.
Anyway, you have something in the middle: inherit from built-in forms and customize them.
I've been getting lots of answers from stackoverflow now that I'm in Django just by searching. Now I hope my question will also create some value for everybody.
In choosing Django, I was hoping there was some similar mechanism to the way you can do partials in ROR. This was going to help me in two ways. One was in generating repeating indexed forms or form elements, and also in rendering only a piece of the page on the round trip.
I've done a little bit of that by using taconite with a simple URL click but now I'm trying to get more advanced. This will focus on the form issue which boils down to how to iterate over a secondary object.
If I have a list of photo instances, each of which has a couple of parameters, let's say a size and a quantity. I want to generate form elements for each photo instance separately. But then I have two lists I want to iterate on at the same time.
Context:
photos : Photo.objects.all()
and
forms = {}
for photo in photos:
forms[photo.id] = PhotoForm()
In other words we've got a list of photo objects and a dict of forms based on the photo.id.
Here's an abstraction of the template:
{% for photo in photos %}
{% include "photoview.html" %}
{% comment %}
So here I want to use the photo.id as an index to get the correct form. So that each photo has its own form. I would want to have a different action and each form field would be unique. Is that possible? How can I iterate on that? Thanks!
Would it be a with? In Python of course it's form = forms[photo.id] but here?
{% endcomment %}
Quantity: {{ oi.quantity }} {{ form.quantity }}
Dimensions: {{ oi.size }} {{ form.size }}
{% endfor %}
What can I do about this simple case. And how can I make it where every control is automatically updating the server instead of using a form at all?
Thanks!
James
I'm not sure I understand your question, but here's what I think you want, expressed in pseudo-code:
for photo in photos:
form = forms[photo.id]
generate_some_html(photo, form)
Probably the best way to achieve this is with inclusion tags: http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags . Basically, it's a custom tag that relies on another template, similar to an RoR partial. The details can be found in the link I provided, but what you basically need to do is
create a package names "templatetags" in one of your app directories
create a module in that package. Let's take foo_tags.py for example.
Add the following boilerplate to foo_tags.py:
from django import template
register = template.Library()
Write your custom tag, which implements generate_some_html. Make it take the caller's context:
#register.inclusion_tag('relative/path/to/some/template.html', takes_context=True)
def foo_tag(context):
photo = context['photo'] # loop variable in parent template
form = context['forms'][photo.id]
# further computation that you need in order to setup the
# context for relative/path/to/some/template.html can be
# done here...
return locals()
Use the context returned by foo_tag in relative/path/to/some/template.html.
Add {% load foo_tags %} to the parent template. You should probably put this near the top, the same way you put imports near the top of a .py file.
Use your new custom tag in the parent template:
{% for photo in photos %}
{% foo_tag %}
{% endfor %}
Django doesn't comme with backed AJAX like RAIL, but it let you choose any lib you want to use from the start.
You can do what you want by creating custom widgets and using form media.