在ModelChoiceField内部渲染图像列表

时间:2019-08-27 13:59:27

标签: django django-forms django-templates geodjango django-2.2

我使用Bootstrap4开发了一个表单,用于创建博客文章。在具有两个ForeignKey的模型上链接此表单:FileField和ImageField。

如果我使用默认的表单呈现方法({{ form.as_p }}),则可以创建博客帖子,但FileField和ImageField均使用一种上载类型的名称呈现。我想看到的是图像,而不是单个图像的名称。然后,我尝试使用它:

<div class="form-group mb-4">
    <select class="form-control">
        {% for img in geoform.image %}
            <option value="{{ img.pk }}"> <img class="img-fluid" src="{{ img.path }}" alt="{{ img.name }}"> </option>
        {% endfor %}
    </select>
</div>

但是我看到一个空列表。在页面源代码中,我看到以下内容:

<select class="form-control">
        <option value=""> <img class="img-fluid" src="" alt=""> </option>
        <option value=""> <img class="img-fluid" src="" alt=""> </option>
        <option value=""> <img class="img-fluid" src="" alt=""> </option>
        <option value=""> <img class="img-fluid" src="" alt=""> </option>
</select>

我在图像模型中有四个对象。由于我不了解对象无法正确渲染的原因。

这是模型:

class GeoBlogFile(models.Model):
    name = models.CharField(max_length=70)  
    path = models.FileField(upload_to='geoblog/documents/%Y/%m/%d')

    def __str__(self):
        return self.name

class GeoBlogImage(models.Model):
    name = models.CharField(max_length=70)  
    path = models.ImageField(upload_to='geoblog/images/%Y/%m/%d')

    def __str__(self):
        return self.name

class GeoBlog(models.Model):
    title = models.CharField(max_length=70, unique=True)
    slug_title = models.SlugField(max_length=70, unique=True)
    contents = models.TextField(max_length=200)
    file = models.ForeignKey(GeoBlogFile, on_delete=models.CASCADE, related_name="related_file", blank=True, null=True)
    image = models.ForeignKey(GeoBlogImage, on_delete=models.CASCADE, related_name="related_image", blank=True, null=True)
    publishing_date = models.DateTimeField(default=timezone.now, blank=True)
    geom = models.PointField(srid=3857)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("single_geopost", kwargs={"slug_title":self.slug_title})

这是表格:

class GeoBlogPostForm(forms.ModelForm):
    title = forms.CharField(
        max_length=70,
        widget=forms.TextInput(
            attrs={
                "placeholder": "Titolo",
                "type": "text",
                "id": "id_name",
                "class": "form-control form-control-lg",
                }
            ),
        )
    contents = forms.CharField(
        max_length=200,
        widget=forms.Textarea(
                attrs={
                    "placeholder": "Contenuti",
                    "type": "text",
                    "id": "id_contents",
                    "class": "form-control",
                    "rows": "2",
                    }
            ),
        )
    file = forms.ModelChoiceField(
        widget= forms.Select(
            attrs={
                "id": "id_file",
                "class": "custom-select",
                }
            ),
        empty_label="Select the file",
        queryset= GeoBlogFile.objects.all(),
        )
    image = forms.ModelChoiceField(
        widget= forms.Select(
            attrs={
                "id": "id_image",
                "class": "custom-select",
                }
            ),
        empty_label="Select the image",
        queryset= GeoBlogImage.objects.all(),
        )
    geom = forms.PointField(
        widget=forms.OSMWidget(
            attrs={
                'default_lat': 0,
                'default_lon': 0,
                'default_zoom': 2,
                }
            ),
        )
    publishing_date = forms.DateTimeField(
        widget=forms.DateTimeInput(
            attrs={
                "placeholder": "dd/mm/yyyy HH:MM:SS",
                "type": "text",
                "formats": "%m/%d/%Y %H:%M:%S",
                "id": "publishing_date_field",
                'class': 'form-control',
                'data-target': '#publishing_date_field',
                }
            ),
        )

    class Meta:
        model = GeoBlog
        fields = ['title', 'contents', 'file', 'image', 'publishing_date', 'geom']

以前的表单组是许多人的最后尝试。是否可以渲染图像列表而不是图像名称列表?

1 个答案:

答案 0 :(得分:1)

您要遍历geoform.image,但这就是BoundField的{​​{1}}。您有点倒霉,因为它是geoform,通过它的迭代可以得到子窗口小部件的列表,但它与实际图像无关。

要获取图像,必须使用实际的ChoiceField

Field

此外,请确保您在{% for img in geoform.fields.image.queryset %} 标记中使用的url是上载文件的正确前缀的媒体url:

<img>