Working on an app, I initially started developing the UI via QT (PySide2) but I paused it to work on a full "online version" via Django.
The fact is that I'm learning/discovering the framework and how it works step after step.
For all HTML I'm building those on Bootstrap Studio which help me to save A LOT of time and of course make things totally easier for me.
My current problem is that I just discovered how not simply inputs/forms work in Django (My own opinion !). My app works with several bootstrap modals in order to Add/Edit "element" which are the kind of instances of my app and which will be write/read/edit in the database.
The problem here is I already created all HTML pages and related bootstrap-modals and I can't find any way on the internet to link my existing bootstrap-modals to Django forms.
As far as I understood Django forms "caricaturaly" works like this: Django generates a form that you have to dynamically integrate into your HTML.
The fact is it doesn't really arrange me because :
I already have my bootstrap-modals with their inputs looking how I want
I don't really want a bad looking forms as Django generates
I have other elements in the form which are not related to a form (progress bar)
Any other things I have no idea about since I am a beginner in Web!
Therefore, my main question here would be: Is there any simple/accessible way to get the inputs as it would be via QT, by this I mean :
Opening the modal
Filling Input_1, Input_2, Input_3
Any way in Django files to get those inputs and then saves those in DB (one by one)
My apologies if really looks dumb here but I am really new to Django/Web, I know CSS/HTML syntax, I have NO knowledge in JavaScript and I would say that my Python level is Intermediate (enough for all my back-end uses).
Thank you in advance for your help!
A simple example of using a form for validation/processing but not html generation.
Assume we have this existing form
<form action="/some-url" method="POST">
<input id="foo" name="foo" type="text"/>
<input id="bar" name="bar" type="text"/>
<input id="baz" name="baz" type="text"/>
</form>
you can represent it with this Django form:
class MyForm(forms.Form):
# Field names should match the 'name' attributes in the html inputs
foo = forms.CharField()
bar = forms.CharField()
baz = forms.CharField()
And use it in view like this
def my_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# Do stuff
return HttpRedirectResponse('/success')
# No need to pass the a form to the template, because we aren't
# using it to generate html.
return render(request, 'view.html', {})
If you want to use a field from the html form separately, without using a Django form at all, access it directly:
some_val = request.POST['some_val']
(beware of false booleans and disabled fields, which will not be present in request.POST).
Related
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.
I'm currently learning django from the 'How to tango with django' site and i'm unable to understand the chapter dealing with forms.
Appreciate it if someone would help me out.
http://www.tangowithdjango.com/book17/chapters/forms.html
the first step is to create a forms page which maps to models.py. I seem to understand this part. I also understand that we create
a view to process the data acquired from these forms. I'm not able to understand the below code in the views page.
from rango.forms import CategoryForm
def add_category(request):
# A HTTP POST?
if request.method == 'POST':
form = CategoryForm(request.POST)
else:
# If the request was not a POST, display the form to enter details.
form = CategoryForm()
How do the urlmapper know that a request method is POST or GET before the user actually enters any data in the form?
On a similar note, when would a form have a get method?
form = CategoryForm(request.POST) - would someone explain this to me? CategoryForm looks to be a class which is already inheriting from another class
what does the request.POST argument convey ?
1) The urlmapper does by default not care about GET or POST request method. It will route any request to the given view-function.
Normally, your form html-code will look like this:
<form method="post" action="some_url">
...
</form>
So, when you submit the form, the data will be send to some_url with the specified method, in this case post.
You may want to read something about when to use GET or POST, normally forms are transferred using POST.
2) form = CategoryForm(request.POST) will bind the values provided in the request's POST-dictionary to the form. You may say, it prepopulates this. This way, further working with the form (like validating it by calling form.is_valid()) will be made possible.
Perhaps you should investigate further on Django forms and modelforms by reading some official documentation.
Why do you think the URL mapper knows if it's a post it a get? It doesn't, and it doesn't care.
The thing you are missing is that this view has two responsibilities: showing the initial form (on GET) and processing the submitted form (on POST).
Your second question shows an unfamiliarity with basic Python syntax. request.POST is the parameter to the initialisation of the form instance.
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'm writing a Django app whose data will be coming from different sources, including Excel spreadsheets. I've written some code to do an initial import from those sheets, but I don't like the idea to re-import the whole data each time a row is added - and my client does not want to re-type the data himself.
A possible solution would be to add a form with a simple textarea where the user could copy-paste a whole line of the spreadsheet. Then a view could split the data, pre-process it and post it to the standard admin form for the corresponding object.
Ideally, it would behave like the user has really posted from this form: if the data validates, the object is created and if not, the (admin) form is re-displayed with the nice red error boxes.
So I thought I would just need something like
from django.shortcuts import redirect
[...]
return redirect(to, method=POST, *args)
but it doesn't seem to be available.
I also thought of passing the data as a big query string like http://.../admin/app/object/add/?ID=1234&name=toto&... but my model has many fields, with one-to-many and many-to-many inlines, possibly long textfields, etc. so this approach seems like more trouble than necessary.
Any idea how to obtain something like a POST redirect? or another approach to this problem?
If you're already writing code that is specific to your form, why not create the objects in that same function instead of trying to fake a POST request to the admin site?
To me, it sounds more difficult to use the default admin form than to use your existing pre-processing view to start creating or updating objects.
I'd just hook up your pre-processing view to your ModelAdmin definition via the get_urls method, set up a template that could be as simple as
<form action="." method="post">
<textarea name="data"></textarea>
<input type="submit" value="submit" />
</form>
and manually process the data in the input form request.POST.get('data', '').split(',') (or what have you) and start populating your models.
When done, send a message and redirect back to your app view or changelist view.
request.user.message_set.create(message="Finished populating X models")
return http.HttpResponseRedirect('../')
For this, you should step away from the built-in admin interface.
Create your own ModelForm http://docs.djangoproject.com/en/dev/topics/forms/modelforms/
Create your own view functions that does validation and POST.
This should probably be a 2-step transaction.
view_function_1
if method is GET, present the empty form.
if method is POST, they have pasted a value into the text box and filled in the "other" fields.
Parse the data in the text box.
For fields which are empty, fill in the missing values from the text box.
Put the form's data into the session.
Do a redirect to a URL that will move to view_function_2
view_function_2
If the method is GET, fetch the form data from the session, fill things in and
present the form with data.
If the method is POST, validate and save the results.
redirect to a page which will display the details to the user.