Django基于类的表单,带有从模型/数据库中填充的下拉框数据。

huangapple go评论52阅读模式
英文:

Django class-based form with dropdowns populated with data from model / db

问题

这是我的Django代码:

forms.py

from django import forms

class MyForm(forms.Form):
    name = forms.ChoiceField(choices=YourChoicesHere)  # 使用ChoiceField来创建下拉框
    location = forms.ChoiceField(choices=YourChoicesHere)  # 使用ChoiceField来创建下拉框

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})

模板 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)  # 使用OneToOneField来创建下拉框
    location = models.ForeignKey(Location, on_delete=models.CASCADE)  # 使用ForeignKey来创建下拉框
    date = models.DateTimeField(auto_now_add=True)
    # ...

要使字段成为下拉框,你需要在forms.pymodels.py中使用ChoiceField来替代CharField。此外,你需要在ChoiceFieldchoices参数中提供选项的数据。你可以从数据库中获取数据并将其传递给ChoiceField。在views.pyget方法中,创建一个空的表单实例并传递给模板,以便在模板中进行选择。

英文:

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 = &#39;form.html&#39;
    form_class = MyForm
    success_url = &#39;home&#39;

    def get(self, request, *args, **kwargs):
        form = self.form_class
        return render(request, &#39;form.html&#39;, {&#39;form&#39;: form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            form.save()
            return redirect(&#39;home&#39;)
        else:
            return render(request, self.template_name, {&#39;form&#39;: form})

template form.html

   &lt;form method=&quot;post&quot; action=&quot;{% url &#39;form&#39; %}&quot;&gt;
        {% csrf_token %}
        {{ form.as_p }}
        &lt;input type=&quot;submit&quot; class=&quot;btn btn-primary btn-block py-2&quot; value=&quot;OK&quot;&gt;
   &lt;/form&gt;

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.

答案1

得分: 1

你应该使用ModelChoiceField而不是CharField,所以:

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类没有save()方法,不像模型表单(modelforms),所以你应该在form_valid()方法中手动使用cleaned_data保存表单,如下:

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)
英文:

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 = &#39;form.html&#39;
    form_class = MyForm
    success_url = reverse_lazy(&#39;home&#39;)

    def form_valid(self, form):
        name = form.cleaned_data[&#39;name&#39;]
        location = form.cleaned_data[&#39;location&#39;]
     
        MyModel.objects.create(name=name, location=location)
        return super().form_valid(form)

huangapple
  • 本文由 发表于 2023年2月10日 03:36:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403606.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定