Django class-based form with dropdowns populated with data from model / db
Question:
This my Django code:
forms.py
from django import forms
class MyForm(forms.Form):
name = forms.CharField()
location = forms.CharField()
views.py
class MyFormView(FormView):
template_name = 'form.html'
form_class = MyForm
success_url = 'home'
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, 'form.html', {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
return render(request, self.template_name, {'form': form})
template form.html
<form method="post" action="{% url 'form' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary btn-block py-2" value="OK">
</form>
models.py
class MyModel(models.Model):
# ...
name = models.OneToOneField(Person, on_delete=models.CASCADE))
location = models.ForeignKey(Location, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
# ...
I want both two fields (name, location) to be drop-downs (combobox-es) not CharFields, and I want to populate their entries / values with data coming from db (django models). How can I do that? I am completely new to CBV idea.
Answers:
You should use ModelChoiceField
instead of CharField
so:
from django import forms
from .models import YourModelName
class ReleaseForm(forms.Form):
name = forms.ModelChoiceField(queryset=YourModelName.objects.all())
location = forms.ModelChoiceField(queryset=YourModelName.objects.all())
Form
class doesn’t have a save()
method unlike modelforms so you should manually save the form using cleaned_data
in form_valid()
method as:
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views.generic import FormView
from .forms import MyForm
from .models import MyModel
class MyFormView(FormView):
template_name = 'form.html'
form_class = MyForm
success_url = reverse_lazy('home')
def form_valid(self, form):
name = form.cleaned_data['name']
location = form.cleaned_data['location']
MyModel.objects.create(name=name, location=location)
return super().form_valid(form)
This my Django code:
forms.py
from django import forms
class MyForm(forms.Form):
name = forms.CharField()
location = forms.CharField()
views.py
class MyFormView(FormView):
template_name = 'form.html'
form_class = MyForm
success_url = 'home'
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, 'form.html', {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
return render(request, self.template_name, {'form': form})
template form.html
<form method="post" action="{% url 'form' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary btn-block py-2" value="OK">
</form>
models.py
class MyModel(models.Model):
# ...
name = models.OneToOneField(Person, on_delete=models.CASCADE))
location = models.ForeignKey(Location, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
# ...
I want both two fields (name, location) to be drop-downs (combobox-es) not CharFields, and I want to populate their entries / values with data coming from db (django models). How can I do that? I am completely new to CBV idea.
You should use ModelChoiceField
instead of CharField
so:
from django import forms
from .models import YourModelName
class ReleaseForm(forms.Form):
name = forms.ModelChoiceField(queryset=YourModelName.objects.all())
location = forms.ModelChoiceField(queryset=YourModelName.objects.all())
Form
class doesn’t have a save()
method unlike modelforms so you should manually save the form using cleaned_data
in form_valid()
method as:
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views.generic import FormView
from .forms import MyForm
from .models import MyModel
class MyFormView(FormView):
template_name = 'form.html'
form_class = MyForm
success_url = reverse_lazy('home')
def form_valid(self, form):
name = form.cleaned_data['name']
location = form.cleaned_data['location']
MyModel.objects.create(name=name, location=location)
return super().form_valid(form)