DJANGO:数据库相关的组合框保持空白。没有显示任何项目。

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

DJANGO: database dependent combobox remains empty. No items appear

问题

以下是翻译好的部分:

我想创建一个下拉框,并在其中显示数据库表(城市名称)中的数据。页面位于app1/home.html。我创建了文件并迁移了数据库,但下拉框仍然为空。我不知道我做错了什么。我是Django的新手,很抱歉。我阅读了许多教程和问题,但没有解决。

我应该如何修复下拉框,并正确显示City_Name?谢谢!!!

models.py

数据库表名为app1_select_city,其中包含idCity_Name

from django.db import models 

class Select_City(models.Model): 
    Select_City= models.IntegerField() 

    def __str__(self):
        return self.Select_City

forms.py

from .models import Select_City
class TestForm(forms.Form):
    some_input = forms.CharField(max_length=100)
    city = forms.ModelChoiceField(queryset=Select_City.objects.all())

    class Meta:
        model = Select_City
        fields = ('City_Name',)

views.py

def combobox(request):
  query_results = Select_City.objects.all()

  if request.method == "POST":
        form = TestForm(request.POST)
  context = {'form': form, 'query_results': query_results}
  return render(request, 'app1/home.html', context)

home.html

<form method="post" novalidate>
  {% csrf_token %}
  <select id="sel_city" name="cities">
    <option value="{{ query_results }}">Select</option>
    {% for item in query_results  %}
    {% endfor %}
  </select>
</form>

请注意,你的HTML文件中的下拉框选项还需要调整,以便正确显示City_Name

英文:

I would like to create a combobox and display data from a database table (names of cities) inside it. The page is app1/home.html. I created the files and migrated the database, but the combobox remains empty. I don't know what I did wrong. I'm new to Django, sorry. I have read many tutorials and questions, but I have not solved.

How can I fix the combobox and correctly display City_Name in it? Thank you!!!

models.py

The table of database is called app1_select_city, while inside there is: id, and City_Name

from django.db import models 

class Select_City(models.Model): 
    Select_City= models.IntegerField() 

    def __str__(self):
        return self.Select_City

forms.py

from .models import Select_City
class TestForm(forms.Form):
    some_input = forms.CharField(max_length=100)
    city = forms.ModelChoiceField(queryset=Select_City.objects.all())

    class Meta:
        model = Select_City
        fields = (&#39;City_Name&#39;,)

views.py

def combobox(request):
  query_results = Select_City.objects.all()

  if request.method ==&quot;POST&quot;:
        form = TestForm(request.POST)
  context = {&#39;form&#39;: form, &#39;query_results&#39;: query_results}
  return render(request, &#39;app1/home.html&#39;, context)

home.html

&lt;form method=&quot;post&quot; novalidate&gt;
  {% csrf_token %}
  &lt;select id=&quot;sel_city&quot; name=&quot;cities&quot;&gt;
    &lt;option value=&quot;{{ query_results }}&quot;&gt;Select&lt;/option&gt;
    {% for item in query_results  %}
    {% endfor %}
  &lt;/select&gt;
&lt;/form&gt;

答案1

得分: 1

  1. models.py 中:
from django.db import models 

class Select_City(models.Model): 
    City_Name = models.CharField(max_length=100) 

    def __str__(self):
        return self.City_Name

    class Meta:
        db_table = 'app1_select_city'

db_table 属性确保该模型链接到名为 app1_select_city 的表。此外,由于您可以直接返回 City_Name,它是一个字符字段而不是整数字段,因此您可以像您想要的那样在 forms.py 中重用它。

  1. home.html 中:
    为了在下拉框中显示选项,您需要为 query_results 查询集中的每个对象添加一个 option 元素。
    这将为查询集中的每个城市创建一个选项,选项值为 id,选项标签为 City_Name。
<form method="post" novalidate>
  {% csrf_token %}
  <select id="sel_city" name="city">
    <option value="">选择城市</option>
    {% for city in query_results %}
      <option value="{{ city.id }}">{{ city.City_Name }}</option>
    {% endfor %}
  </select>
</form>

另一个快速编辑提示:
您应该在 views.py 中在 if 块之外初始化您的 form,以确保表单始终被初始化。
if 块之外添加 form = TestForm()

英文:

I think the issue mainly pertains around your models.py & home.html

  1. In models.py:
from django.db import models 
class Select_City(models.Model): 
    City_Name = models.CharField(max_length=100) 

    def __str__(self):
        return self.City_Name

    class Meta:
        db_table = &#39;app1_select_city&#39;

The db_table attr makes sure that the model is linking to your app1_select_city table.
Moreover since you can directly return the City_Name, which is a char field not an int field, then you can reuse it in your forms.py as you wanted to.

  1. In home.html, :
    To display the options in the combobox, you need to add an option element for each object in query_results queryset.
    This will create an option for each city in the queryset, with the id as the option value and the City_Name as the option label.
&lt;form method=&quot;post&quot; novalidate&gt;
  {% csrf_token %}
&lt;select id=&quot;sel_city&quot; name=&quot;city&quot;&gt;
    &lt;option value=&quot;&quot;&gt;Select a city&lt;/option&gt;
    {% for city in query_results %}
        &lt;option value=&quot;{{ city.id }}&quot;&gt;{{ city.City_Name }}&lt;/option&gt;
    {% endfor %}
&lt;/select&gt;

Another quick edit:
You should init your form in views.py outside of the if-block, just so the form is always initialised
Add form = TestForm() outside the if-block

答案2

得分: 1

以下是您要翻译的内容:

好的,这里有很多内容需要处理。

Your model does not have a name field! It just has an IntegerField called Select_City which is the same name as the class. That is not good. Usually you want to write your model without underscores with Camelcase and your fields with underscores and no capital letters.

from django.db import models 

class City(models.Model): 
    name = models.CharField(max_length=30) 

    def __str__(self):
        # here you want to return the name
        # print function on an instance of this model then returns the name
        return self.name

After these changes you have to python manage.py makemigrations and python manage.py migrate. In case of issues I recommend deleting the database and migrations and then start again with mentioned commands.

forms.py. Why do you need input here? If you just want to select one of the models you just need the ModelChoiceField

from .models import City

class SelectCityForm(forms.Form):
    city = forms.ModelChoiceField(queryset=City.objects.all())

    class Meta:
        model = City
        fields = ('name',)

Ok now when it comes to your view you want to separate its logic into a get and a post request. GET request when the user "goes" to your form when he is about to select a city. POST request after he selected a form when he pressed submit at the form. Then on POST request you want to display what you are confusingly referring to as "combobox". I call it city_detail. on GET you don't need to create the query_results here since this already happens within the form. Whereas on POST you want to filter the queryset for the selected city id.

def city_detail(request):
    form = CitySelectForm()
    object = None
    if request.method == "POST":
        form = CitySelectForm(request.POST)
        if form.is_valid():
            city_id = form.cleaned_data['city']
            object = City.objects.get(id=city_id)


    context = {'form': form, 'object': object}
    return render(request, 'app1/home.html', context)

Your template should show the form on GET and the City-Details (object) on POST

<form action="/url-to-city_detail-view/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>
{% if object %}
Here you can embed data of your city such as the ID: {{ object.id }} or the Name: {{ object.name }}. Since you defined the __str__ method you can also just put {{ object }} and it will give the name.
{% endif %}

All in all I have to say this is still not the cleanest approach, since you would normally "select" an Object of your database with parameters that you pass to the URL.

英文:

Ok, here is a lot to tackle.

Your model does not have a name field! It just has an IntegerField called Select_City which is the same name as the class. That is not good. Usually you want to write your model without underscores with Camelcase and your fields with underscores and no capital letters.

from django.db import models 

class City(models.Model): 
    name = models.CharField(max_length=30) 

    def __str__(self):
        # here you want to return the name
        # print function on an instance of this model then returns the name
        return self.name

After these changes you have to python manage.py makemigrations and python manage.py migrate. In case of issues I recommend deleting the database and migrations and then start again with mentioned commands.

forms.py. Why do you need input here? If you just want to select one of the models you just need the ModelChoiceField

from .models import City

class SelectCityForm(forms.Form):
    city = forms.ModelChoiceField(queryset=City.objects.all())

    class Meta:
        model = City
        fields = (&#39;name&#39;)

Ok now when it comes to your view you want to separate its logic into a get and a post request. GET request when the user "goes" to your form when he is about to select a city. POST request after he selected a form when he pressed submit at the form. Then on POST request you want to display what you are confusingly referring to as "combobox". I call it city_detail. on GET you don't need to create the query_results here since this already happens within the form. Whereas on POST you want to filter the queryset for the selected city id.

def city_detail(request):
    form = CitySelectForm()
    object = None
    if request.method == &quot;POST&quot;:
        form = CitySelectForm(request.POST)
        if form.is_valid():
            city_id = form.cleaned_data[&#39;city&#39;]
            object = City.objects.get(id=city_id)


    context = {&#39;form&#39;: form, &#39;object&#39;: object}
    return render(request, &#39;app1/home.html&#39;, context)

Your template should show the form on GET and the City-Details (object) on POST

&lt;form action=&quot;/url-to-city_detail-view/&quot; method=&quot;post&quot;&gt;
    {% csrf_token %}
    {{ form }}
    &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
&lt;/form&gt;
{% if object %}
Here you can embed data of your city such as the ID: {{ object.id }} or the Name: {{ object.name }}. Since you defined the __str__ method you can also
just put {{ object }} and it will give the name.
{% endif %}

All in all I have to say this is still not the cleanest approach, since you would normally "select" an Object of your database with parameters that you pass to the url.

huangapple
  • 本文由 发表于 2023年6月29日 13:32:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76578284.html
匿名

发表评论

匿名网友

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

确定