python - Django 从 postgresql 数据库填充下拉菜单的完整示例

标签 python django django-forms django-templates django-views

我对 django 很陌生(使用 django 2.1.5 和 python 3.7),我似乎不知道如何添加一个下拉菜单,显示我的 postgresql 数据库中的表中的一个字段的元素。我希望最终允许用户从下拉菜单中选择一个元素,我将使用该选择构建一个查询并返回该查询的结果。但我已经被下拉菜单困住了。 这是 models.py 文件中的我的模型

class Locations(models.Model):
    gid = models.AutoField(primary_key=True)
    field_gid = models.BigIntegerField(db_column='__gid', blank=True, null=True)  # Field renamed because it contained more than one '_' in a row. Field renamed because it started with '_'.
    name_location= models.CharField(unique=True, max_length=254, blank=True, null=True)
    x = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    y = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    z = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    geom = geomodels.PointField(srid=3912)

    def __str__(self):
        return self.name_location

    class Meta:
        managed = False
        db_table = 'locations'
        verbose_name_plural = "Locations"

这是 forms.py 文件中我的表单:

from .models import Locations
class LocationsForm(forms.ModelForm):
    class Meta:
        model = Locations
        fields = ('name_location',)
        #Down here is what I actually thought I need, but maybe I am not using it right 
        locations_list = forms.ModelChoiceField(queryset=Locations.objects.all().only('name_location').order_by('name_location'))

然后,在我的views.py 文件中:

from .forms import LocationsForm
def LocationsView(request):
    form = LocationsForm
    return render(request, 'geoportal/mforest.html', {'form': form})

我的urls.py如下:

from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='geoportal-home'),
path('mforest/', views.LocationsView, name='geoportal-mforest')
]

最后在我的模板 mforest.html 文件中(我只放置了一个摘录,因为 base.html 有一个我在 mforest.html 中扩展的 block 内容):

{% extends "geoportal/base.html" %}
{% block content %}
<div class="col-md-3" style="height: 100vh; border: 2px red; background-color: lightgray">
    <h3>Meteo Stations of the SFI</h3>
    <form method="GET">
        {% csrf_token %}
        {{ form }}
    </form>
    </div>
<div class="col-md-9">
    <h3>Output of the query</h3>
    <table width="100%" class="blueTable"> </table>
</div>
{% endblock content %}

对于模板文件,我还尝试了一些迭代查询集结果的建议。但是,我尝试过的解决方案都没有显示我的下拉菜单。我确信我做错了什么,因为我没有得到预期的结果,但我不知道该纠正什么。 附言。我没有收到错误。它根本不显示任何东西。 预先感谢您的帮助!

编辑:更多关于我想要实现的目标,please click here查看我的页面上有什么(尽管几乎什么也没有)。 (不要注意我在这个问题中用“name_location”替换的标签“kraj_odvze”)。现在;我真正想要的是一个下拉菜单,其中包含数据库中“name_location”字段中的元素,而不是文本框。我将进一步包括一个日期时间范围选择器和一个按钮来执行查询以在页面的右侧 div 上呈现为表格和图形。

最佳答案

感谢@art06的评论,我明白了这个问题。 由于我要查询另一个表(“Meteo”),该表有一列表示指向“Locations”表的“name_location”列的外键,因此我应该使用“Meteo”表而不是“Locations” .

因此,models.py 文件如下:

class Locations(models.Model):
    gid = models.AutoField(primary_key=True)
    field_gid = models.BigIntegerField(db_column='__gid', blank=True, null=True)  # Field renamed because it contained more than one '_' in a row. Field renamed because it started with '_'.
    name_location = models.CharField(unique=True, max_length=254, blank=True, null=True)
    x = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    y = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    z = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    geom = geomodels.PointField(srid=3912)

    def __str__(self):  # __unicode__ for py2
        return self.name_location

    class Meta:
        managed = False
        db_table = 'locations'
        verbose_name_plural = "Locations"


class Meteo(models.Model):
    time = models.DateTimeField()
    air_temp = models.FloatField(blank=True, null=True)
    soil_temp = models.FloatField(blank=True, null=True)
    precipitation = models.FloatField(blank=True, null=True)
    global_rad = models.FloatField(blank=True, null=True)
    relative_hum = models.FloatField(blank=True, null=True)
    wind_speed = models.FloatField(blank=True, null=True)
    swc = models.FloatField(blank=True, null=True)
    pressure = models.FloatField(blank=True, null=True)
    location = models.ForeignKey(Locations, models.DO_NOTHING, db_column='location', to_field='name_location')  # to_field is required because the Foreignkey field is a text
    id = models.BigAutoField(primary_key=True)

    class Meta:
        managed = False
        db_table = 'meteo'
        unique_together = (('time', 'id'),)
        verbose_name_plural = "Meteo"

和 forms.py 如下:

from django import forms
from .models import Meteo
class LocationsForm(forms.ModelForm):
    class Meta:
        model = Meteo
        fields = ('location',)

通过更改我帖子中的内容,django 将字段格式设置为下拉菜单,并且显示效果良好。

因此,我在这里没有得到的关键点是: 即使不编写 ModelChoiceField,当 ModelForm 与外键一起使用时,它也会自动创建一个下拉菜单。

关于python - Django 从 postgresql 数据库填充下拉菜单的完整示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54720439/

相关文章:

python - 在 Python 中选择数据框中每一行的两个子字符串之间的字符串

python - 更改一个列表也会意外地更改另一个列表

python - Dictionary of lists 到 Dictionary

python - 我什么时候应该更喜欢 random.choice() 而不是 random.randint?

Django DateTimeField 输入表单

django - Django ORM如何舍入平均结果

django - Django 中的全局 formfield_overriding

django - 如何将 CSS 类添加到 Django 内置表单

python - View 中的 Django 过滤器

django - 关于如何在 django 中编写自定义表单字段的教程?