I am setting up a simple html page, the page captures the information that the user entered and based on the information that the user entered makes a new page. The problem is that I cant get back the information entered by the user at the backed and I dont understand where I am going wrong.
My views file is setup like this:
def suggestion(request):
if request.method == 'POST':
form = BusinessName(request.POST)
if form.is_valid():
data=form.cleaned_data
context = insert_function_here(data)
return render( request,'mainpage.html', context)
else:
form = BusinessName()
context = {'form':form}
return render( request,'mainpage.html', context)
My forms.py is setup like this:
class BusinessName(forms.Form):
business_name = forms.CharField(widget = forms.HiddenInput(), required = False)
The relevant part of my html is set up like this:
<form id="user_input_form" method="post" action="http://127.0.0.1:8000/textinsighters/suggestion">
Enter Your Business Name : <input type="text" list="browsers" name="browser" id="user_input">
{% csrf_token %}
{{ form }}
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
<button onclick="myFunction()">Submittt</button>
</form>
<script>
function myFunction() {
document.getElementById("id_business_name").value = document.getElementById("user_input").value;
document.getElementById("user_input_form").submit();
}
</script>
I want an auto-completing list so thats why I am creating a form in html. I get the user input, set the value of the Django form field to the value that the user entered and submit it. I should get something back but the variable 'data' in views doesnt contain the user input.
Thanks
You are using a forms.HiddenInput() as the widget and then add the form field yourself. This doesn't work that way. What if you change the field class to TextInput:
class BusinessName(forms.Form):
business_name = forms.CharField(widget = forms.TextInput())
If you're goal is to add custom attributes to the widget, then this can be done by providing an attrs dictionary:
class BusinessName(forms.Form):
business_name = forms.CharField(widget = forms.TextInput(attrs={
'list': 'browser'
}))
Or you could have a look at the django-widget-tweaks package to add attributes in the template.
Related
Am trying to save dropdown in django without using django forms am directly getting the form values to views.
This is my view:
class WelcomeForm(ModelForm):
message = forms.CharField(widget=forms.Textarea)
class Meta:
model = Welcome
fields = [ 'message', 'courses']
try:
courses = Course.objects.all()
except ObjectDoesNotExist:
courses = None
form = WelcomeForm()
if request.method == 'POST':
form = WelcomeForm(request.POST)
if form.is_valid():
_process = form.save(commit=False)
_process.save()
messages.success(request, 'Welcome settings has been added successfully')
context = {'courses': courses}
return render(request, 'welcome/add_form.html', context)
And thus, using courses in my dropdown:
<select class="form-select" data-search="on"name="courses" multiple>
<option></option>
{% for data in courses %}
<option value="{{data.name}}">{{data.name}}</option>
{% endfor %}
</select>
From the above, i can save name of the course, but i also need slug of the course to make user clickable ! HOw to save two values from the selected options ?
Consider this :
{% for user in users.query.all() %}
<tr>
<form method='POST' action="">
<td>{{form.username}}</td>
<td>{{form.description}}</td>
<td>{{form.submit(value="Update")}}</td>
</form>
</tr>
{% endfor %}
For each user this will create a small form that I can update, I want to populate these forms with current database data
What I tried to do in the routes file:
#app.route("/Users")
def listUsers():
users = Users
form = UserForm()
if request.method == 'GET':
for user in users.query.all():
form.username.data = user.username
form.description.data = user.description
return render_template('Users.html', users=users, form=form)
This results in having the data of the last user populating all of the forms, how can I go about fixing this ?
I was thinking of assigning an id to each form that matchs the user, but how would I be able to send a dynamic number of forms ?
It took me a while, but I got a work around, just gonna post it if anyone else has the same issue:
I used javascript ... created a function and called it within the for loop which populated the fields for me
function populateForm(username,description){
var form = document.getElementById('form id here');
form.nextElementSibling.value = username;
form.nextElementSibling.nextElementSibling.textContent = description;
}
note that I used value for input field and textContent for textfield, then inside the for loop i added a script tag
<script>
populateForm('{{user.username}}','{{user,description}}');
</script>
I am creating a newsletter application that requires the user's name and email. However each time I input form data . no change is reflected in the database
models.py
class NewUsers(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
date_added = models.DateField(auto_now_add= True)
class Meta:
verbose_name = "NewUser"
verbose_name_plural = "NewUsers"
def __str__(seld):
return self.email
views.py
def newsletter_subscribe(request):
if request.method == 'POST' :
form = NewUserForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name'] #variable to store cleaned data
email = form.cleaned_data['email']
instance = NewUsers(name= name, email = email)
instance.save()
if NewUsers.objects.filter(email = instance.email).exists():
print("Your email is already added to our database")
else:
instance.save()
print("Thank you for subscribing")
else:
form = NewUserForm()#display empty form
context = {'form':form}
template = "index.html"
return render(request ,template ,context )
Here is my template code
template
<form method="post" action="{%url 'subscribe'%}">
{% csrf_token %}
<label for="id_email_field">Name:</label> <input type="text"
name=""
required="" id="">
<label for="id_email_field">E-mail:</label> <input type="email"
name="email_field"
required="" id="id_email_field">
<button id="id_submit" name="submit" value="Subscribe"
type="submit">Subscribe
</button>
</form>
A few things I notice: First, a view must return an HttpResponse object. E.g., I recommend reading up here: https://docs.djangoproject.com/en/2.1/topics/http/views/ and here: https://docs.djangoproject.com/en/2.1/topics/forms/
So, since apparently you didnt get an error thrown at you pointing to this fact, I assume that the request.method never has been equal "POST". Maybe you could try to find out if this is the case? Therefore: could you also provide your template code, please.
Next, your code in the if form.is_valid() is quite contrived. The most natural thing to do here is just calling form.save(). This will create an instance in your db out of the cleaned form-data. In case, you need to do some adjustments, you can extend like this:
instance = form.save(commit=False)
# add some adjustments (instance.foo = bar)
instance.save()
Last, as noted before, you need to return an HttpResponse object which is usually done via
return redirect(url_name, ..)
Edit: since you now added the template code: Try to first let django render the fields for you: https://docs.djangoproject.com/en/2.1/topics/forms/#rendering-fields-manually
and then have a look at the source code of the template. Your name-input-field is missing a name tag and your email-input-field should have name="email" I think. You can django even let the whole form render for you (see docs again...) Without (correct) name tags in the input fields - it will not be possible to send or correctly assign the data inputted by the user.
I have a page with two forms: a SearchForm and a QuickAddForm. Processing two forms on the same page in Django is not easy, and I'm spent the past two or three days trying to get it to work. I have several unittests that I've been using: a test for each form to make sure it's displaying on the page, a test that a submission of a valid search to the searchform returns the correct results, and three tests for the quickadd form testing that 1) a submission of valid fields results in a new Entry saving to the database; 2) that after an entry is saved, the form redirects to the same page; and 3) that the success message is displayed on that page. For example:
def test_quick_add_form_saves_entry(self):
self.client.post('/editor/', {'quickadd_pre-hw' : 'كلمة'}, follow=True)
self.assertEqual(Entry.objects.count(), 1)
After a lot of work (and helped greatly by the answers and comments on this page: [Proper way to handle multiple forms on one page in Django). I finally got the form working, so that the submitted entry was successfully saved in the database and was redirecting after post. Yay!
Except ... When I open up the page in a browser and try to enter a new Entry, it's clear that it's doing no such thing. You fill out the forms and hit "Save" and ... nothing happens. The page doesn't reload, and the entry isn't added to the database. But the tests (like the one above) testing those very features are passing. (It was at this point that I added the test for the success message, which, at least, has the decency to be failing.) The searchform is working.
I don't know what could possibly be preventing the quickadd form from functioning. Also, I don't understand how the tests could be passing, when the form is not working. What's going on???
Here's the code (Python3, Django1.8 - slightly simplified for clarity):
editor.html
<form id="id_searchform" role="form" method="POST" action="/editor/">
{% csrf_token %}
{{ searchform.as_p }}
<button type="submit" class="btn btn-primary btn-lg"
name="{{searchform.prefix}}">Search</button>
</form>
...
<h1>New entry</h1>
<form id="id_quick_add_form" method="POST" action='/editor/' class="post-form">
{% csrf_token %}
{{ quickaddform.as_p }}
<button type="submit" class="save btn btn-primary"
name='{{quickaddform.prefix}}'>Save</button>
</form>
views.py
def _get_form(request, formcls, prefix):
data = request.POST if prefix in next(iter(request.POST.keys())) else None
return formcls(data, prefix=prefix)
def editor_home_page(request):
if request.method == 'POST':
searchform = _get_form(request, SearchForm, 'searchform_pre')
quickaddform = _get_form(request, QuickAddForm, 'quickadd_pre')
if searchform.is_bound and searchform.is_valid():
query = searchform.cleaned_data['searchterm']
results = Entry.objects.filter(bare_hw__icontains=query)
return render(request, 'dict/editor.html', {
'query' : query,
'results' : results,
'searchform' : searchform,
'quickaddform' : quickaddform,
})
elif quickaddform.is_bound and quickaddform.is_valid():
hw = quickaddform.cleaned_data['hw']
e = Entry.objects.create(hw=hw)
messages.success(request, "Entry %s successfully created." % e.hw)
return redirect('/editor/', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre'),
})
else:
return render(request, 'dict/editor.html', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre')
})
else:
return render(request, 'dict/editor.html', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre')
})
forms.py
class SearchForm(Form):
searchterm = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={
'placeholder': 'English | العربية',
'class' : 'form-control input-lg',
}),
required=True)
class QuickAddForm(Form):
hw = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={
'placeholder': 'ex: مَضْروب',
'class' : 'form-control',
}),
required=True)
I've created a form in django which works fine on desktop browsers, but on mobile browsers when the form submits it just displays a blank screen (doesn't even load the title or an error), am I missing something?
If there's no way to make it work using post, how could I submit a form to locations/<zip code> or use get locations/?zip_code=<zip code>? (I'm a django noob, sorry)
here's the relevant code:
template:
<form action="" method="post">
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
form.py:
class ZipForm(forms.Form):
zip_code = forms.CharField(max_length=10)
views.py:
def zip(request):
if request.method == "POST":
form = ZipForm(request.POST)
if form.is_valid():
zip_code = form.cleaned_data['zip_code']
## get result
return render_to_response("zip.html",{
'title':'Closest Locations',
'results' : results,
'form' : form,
})
else:
form = ZipForm()
return render_to_response("zip.html", {
'form' : form,
'title' : 'Find Locations',
})
url.py:
url(r'^locations/$', 'app.views.zip'),
I wish there was a decent debugger for developing on mobile phones, ugh.
If the form is valid then you do all this fancy stuff... but you forgot to handle the case where the form isn't valid.