I used {{ form }} as seen here
template.html
<h4>Change your details</h4><br>
<form id="edit_form" method='post'>
{% csrf_token %}
{{ form }}
<div class='section group'>
<input id="update_details_button" type='submit' class='btn btn-primary wide' value='Change'/>
</div>
</form>
views.py
def user_view(request, is_admin):
user = request.user
form = myForm()
if request.method == 'POST' and is_admin:
form = myForm(request.POST)
if form.is_valid():
data = form.cleaned_data
user.name = data['name']
user.country = data['country']
user.save()
messages.success(request, 'You have successfully updated your details.')
return render(request, 'mysite/user.html', {
'user': user,
'is_admin': is_admin,
'form': form,
})
My form is as followed
class myForm(forms.Form):
name = forms.CharField(
label="Name",
widget=forms.TextInput(attrs={'placeholder': 'Name'}))
country = CountryField(blank_label='(select country)')
def __init__(self, *args, **kwargs):
super(myForm, self).__init__(*args, **kwargs)
The name field displayed fine on the page but there's no sign of the CountryField, could someone point out the error? The code compiled fine and gives no error while server is running.
CountryField is a model field, not a form field. You're supposed to add it to your user model, in which case a modelform based on that model will automatically generate a country field. Since it looks like you have actually added a field called country to the User model, that's where you should be using CountryField.
However, for reference, to do it manually on a non-model form is slightly more complicated:
from django_countries import widgets, countries
class myForm(forms.Form):
country = forms.ChoiceField(widget=CountrySelectWidget, choices=countries)
In fact it's simpler: https://pypi.org/project/django-countries/#custom-forms
from django_countries.fields import CountryField
class MyForm(forms.Form):
country = CountryField(blank=True).formfield()
If you have installed django_country and it added in installed app than no need to make it from just use like this
{% load countries %}
<select name="country">
{% countries %}
<option value="{{ code }}">{{ name }}</option>
{% endcountries %}
</select>
Related
I have a problem, the urls form works but I can't see the records in url/admin, can I ask for help, thank you :D
SOF wants me to add more details otherwise it doesn't transfer, I don't know what more I can add, generally temapals and urls work.
class Note(models.Model):
"""..."""
notes = models.CharField(max_length=100, unique=True)
description = models.TextField()
class Meta:
verbose_name = "Note"
verbose_name_plural = "Notes"
def __str__(self):
return self.notes
class NoteView(View):
def get(self, request):
if request.method == 'POST':
textN = Note.objects.all().order_by('notes')
form = NoteAddForm(request.POST)
if form.is_valid():
form.save()
return redirect('Files/menu')
else:
textN = NoteAddForm()
return render(request, 'Files/note.html', {'textN': textN})
class NoteAddForm(forms.ModelForm):
"""New note add form"""
class Meta:
model = Note
fields = '__all__'
{% extends 'Files/base.html' %}
{% block title %}Notatnik{% endblock %}
<h2>Notatnik Dietetyka/ Zalecenia ręczne </h2>
{% block content %}
<form action="/send/" method="post">
{% csrf_token %}
{{ textN }}
<label>
<input type="text" class="btn btn-second btn-lg">
<button>Wyślij formularz</button>
</label>
</form>
<button type="button" class="btn btn-primary btn-lg">Powrót</button>
{% endblock %}
Within your NoteView class in views.py file is where the issue is.
I see you have an if statement checking for if request.method == 'POST' within the class-based view get(). The get() is equivalent to if request.method == 'GET'. Therefore, what you might want to do is to override the post() on the class instead. For example:
class NoteView(View):
template_name = 'Files/note.html'
# Use the get method to pass the form to the template
def get(self, request, *arg, **kwargs):
textN = NoteAddForm()
return render(request, self.template_name, {'textN': textN})
# Use the post method to handle the form submission
def post(self, request, *arg, **kwargs):
# textN = Note.objects.all().order_by('notes') -> Not sure why you have this here...
form = NoteAddForm(request.POST)
if form.is_valid():
form.save()
# if the path is... i.e: path('success/', SucessView.as_view(), name='success')
return redirect('success') # Redirect upon submission
else:
print(form.errors) # To see the field(s) preventing the form from being submitted
# Passing back the form to the template in the name 'textN'
return render(request, self.template_name, {'textN': form})
Ideally, that should fix the issue you're having.
Updates
On the form, what I'd suggest having is...
# Assuming that this view handles both the get and post request
<form method="POST"> # Therefore, removing the action attribute from the form
{% csrf_token %}
{{ textN }}
# You need to set the type as "submit", this will create a submit button to submit the form
<input type="submit" class="btn btn-second btn-lg" value="Submit">
</form>
I have big problem, I use MultipleChoic Field into django for "input multiselect",
a user at the possibility of make many choices via the "input select multiple"
I explain to you :
I use this Package : https://pypi.org/project/django-multiselectfield/
this is my model :
class Profil(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,)
skill = MultiSelectField(max_length=500, null=True, blank=True, choices=Skillz)
board = MultiSelectField(max_length=500, null=True, blank=True, choices=Boardz)
this is my form :
class ProfilForm(forms.ModelForm):
skill = forms.MultipleChoiceField(required=False, widget=forms.SelectMultiple, choices=Skillz)
board = forms.MultipleChoiceField(required=False, widget=forms.SelectMultiple, choices=Boardz)
this is my datas of the choices (used in models Profil and form ProfilForm):
Boardz = (
('Reddit', 'reddit.com'),
('Discord', 'discord.com'),
('Twitter', 'twitter.com'),
)
Skillz = (
('Python', 'PythonDjango'),
('Rust', 'RustRocket'),
('Ruby', 'RubyOnRails'),
)
Now the concern problem is views.py and my template.html
<!-- this is what I want with my datas -->
<select multiple class="form-control" id="id_board">
<option>reddit.com</option>
<option>discord.com</option>
<option>twitter.com</option>
</select>
<select multiple class="form-control" id="id_skillz">
<option>PythonDjango</option>
<option>RustRocket</option>
<option>RubyOnRails</option>
</select>
<input type="submit" value="Save">
Into the views.py (which is surely wrong) :
def GetDatasForRegisterForm(request):
form = ProfilForm()
return render_response(request, "registration/register.html",{'form': form})
template.html :
I'm totally lost for display my data choices in select multiple for the user, please guys, how make ?
Update : It's good, I have what I wanted, here is for your members of stack overflow, my solution :
class ProfilForm(forms.ModelForm):
skill = forms.MultipleChoiceField(widget=forms.SelectMultiple, choices=Skillz) # skillz and boardz into choices.py
board = forms.MultipleChoiceField(widget=forms.SelectMultiple, choices=Boardz)
class Meta:
model = Profil
fields = ('skill', 'board',)
in views.py > form = ProfilForm(), return render..
{% for value,text in form.board.field.choices %}
<option value="{{ value }}">{{ text }}</option>
{% endfor %}
This is how i go about generating my template and views.py when dealing with forms.
First here you have defined your form ProfilForm one quick way to know the html generated in your form when your views look like
def GetDatasForRegisterForm(request):
form = ProfilForm()
return render_response(request, "registration/register.html",{'form': form})
In your templates you can just do
<form method="POST" action="<your_action>">
{{ csrf_token }}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
Now when you render this django will create a basic HTML for you, based on model specified. You can copy the HTML and customize the styling and populate the values by accessing the form field values.
Now you haven't asked about how to save this form. But let me do that anyway.
We are going to handle the form post in the same controller which will look like.
def GetDatasForRegisterForm(request):
form = ProfilForm(request.POST or None)
if request.method == "POST" and form.is_valid():
form.save()
return redirect("/<sucess_page>")
return render_response(request, "registration/register.html",{'form': form})
In the view here, i am loading the form with POST data if it exists and checking if the form is valid in the POST and saving it as well. You can where to lead the page to if it is success or error.
I am trying to implement some functionality that allows a user to edit their personal information in a Django project using Django forms. When a user enters the new value in the form and hits enter, they are brought back to the main profile page which is correct however, the values remain the same as before. Below is how I have tried to implement the functionality:
Forms
class UpdateProfile(forms.ModelForm):
email = forms.EmailField(required=False)
first_name = forms.CharField(required=False)
last_name = forms.CharField(required=False)
age = forms.IntegerField(required=False)
height = forms.IntegerField(required=False)
weight = forms.IntegerField(required=False)
class Meta:
#Here are the fields that i want editable
model = User
fields = ('email', 'first_name', 'last_name', 'age', 'height', 'weight')
#Here im trying to commit the changes to the user and return the user
def save(self, commit=True):
super(UpdateProfile, self).__init__(commit)
if commit:
user.save()
return user
Views
def update_profile(request):
args = {}
if request.method == 'POST':
form = UpdateProfile(request.POST, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('account/profile.html'))
else:
form = UpdateProfile()
args['form'] = form
return render(request, 'account/edit_profile.html', args)
HTML
% block head %}
<title>Profile</title>
{% endblock %}
{% block body %}
<div class="container">
<form method="POST" action="{% url 'account:profile' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
<br>
</div>
{% endblock %}
Your form is submitting directly to the view profile page. But that page is presumably not expecting to validate a form. You need to submit it back to the update_profile page, which you normally do by using an action of just "." in the form HTML element.
<form method="POST" action=".">
Once you've done that, you'll see some issues with your form save() method. That method does not do anything useful anyway; you should remove it and let the superclass one be called automatically.
This line seems wrong:
super(UpdateProfile, self).__init__(commit)
You're calling __init__ from the parent class, but the method being called is save()... Also you're refering to a user variable which is (hopefully) not defined in this scope.
In my application, I used email and password for user authentication, which works fine. However, I want to offer the user the option of adding other information to their account like first names, last names, and dates of birth.
I have a change form in myapp.forms.py
class MyChangeForm(forms.ModelForm):
"""
Form for editing an account.
"""
first_name = forms.CharField(widget=forms.TextInput, label="First name")
last_name = forms.CharField(widget=forms.TextInput, label="Last name")
date_of_birth = forms.DateField(widget=forms.DateField, label="Date of birth")
class Meta:
model = MyUser
fields = ['first_name', 'last_name', 'date_of_birth']
def save(self, commit=True):
user = super(MyChangeForm, self).save(commit=False)
if commit:
user.save()
return user
in my views.py, I have the following method for updating
#login_required(login_url='/')
def update_user(request):
if request.method == 'POST':
form = MyChangeForm(request.POST, instance=request.user)
if form.is_valid():
user = form.save(commit=False)
user.save()
return HttpResponseRedirect('/')
else:
form = MyChangeForm(instance=request.user)
return render_to_response('update_user.html', context_instance=RequestContext(request))
and my update_user.html is as follows
{% extends 'user_base.html' %}
{% block content %}
<div class="col-sm-3 col-sm-offset-5">
<h1> Update User</h1>
<form method='POST' action='/update_user/'> {% csrf_token %}
<ul>
{{ form.as_table }}
</ul>
<input type='Submit' class='btn btn-primary btn-block'>
</form>
</div>
{% endblock %}
However, when I serve the file I see this:
As seen here, there's no way to enter my fields!
How can I fix this? It's probably easy, but I'm getting tunnel vision.
erip
Add form to the context, for example like this:
render('update_user.html', {'form': form})
ok i am following the formset. Pretty much i understand that formset is for multiple form.
so this example i just want take four values same time but the ouput in html have only one form is showing.
Shall i want to make extra filed like this <input id="your_name" type="text" name="your_name"> or django will do the rest or any other way to do that.?
models.py
class Article(models.Model):
title = models.CharField(max_length=100)
pub_date = models.DateField(auto_now_add=True)
forms.py
class ArticleForm(forms.Form):
title = forms.CharField()
#pub_date = forms.DateField()
ArticleFormSet = formset_factory(ArticleForm, extra=4, validate_max=True)
views.py
def book(request):
if request.method == 'POST':
formset = ArticleForm(request.POST)
if formset.is_valid():
new = Article()
new.title = request.POST.get('title', None)
#new.pub_date = request.POST.get('pub_date', None)
new.save()
return HttpResponseRedirect(reverse('firstapp.views.book'))
else:
formset = ArticleForm()
return render_to_response('get.html',{'formset': formset}, context_instance = RequestContext(request))
And the html look like this
<form method="post" action="">
{% csrf_token %}
{{ formset.management_form }}
<table>
{% for form in formset %}
{{ form }}
{% endfor %}
</table>
<input type="submit"/>
</form>
In your view you are binding formset to an ArticleForm, not to an ArticleFormSet. Also you are only creating one single Article from it, and you're not even using the form properly (ie: you're getting the title directly from request.POST instead of getting it from your form's cleaned_data). Your view code should look something like this (caveat: untested and possibly buggy code, but at least you'll get the picture).
def book(request):
if request.method == 'POST':
formset = ArticleFormSet(request.POST)
if formset.is_valid():
for data in formset.cleaned_data:
Article.objects.create(title=data['title'])
return HttpResponseRedirect(reverse('firstapp.views.book'))
else:
formset = ArticleFormSet()
return render_to_response('get.html',{'formset': formset},
context_instance = RequestContext(request))
As a last point, I strongly suggest you have a look at ModelForms.