Django – 根据数据库中的数值显示静态文件夹中的图像

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

Django - display image from static folder in accordance to values from DB

问题

我有一个Django应用程序,其中有一个模型用于保存城市、县和国家的代码:

models.py

class AreaMap(models.Model):
    Code = models.AutoField(primary_key=True)
    fCityCode = models.CharField(
        verbose_name='City', max_length=100)
    fCountyCode = models.CharField(
        verbose_name='County', max_length=100)
    fCountryCode = models.CharField(
        verbose_name='Country', max_length=100)

    def __str__(self):
        return self.fCityCode

对于每个城市,我在静态文件夹中有一些静态图像,这些图像不会更改(或者至少如果需要,旧文件将被新文件覆盖,但保持相同的文件名)。图像与数据库中的值之间的对应关系是通过字段fCityCode来实现的:

示例:

对于纽约 - 在数据库中保存为'NewYork',静态文件夹中的图像文件名也是相同的,'NewYork'。

现在,我想在我的HTML模板中显示与数据库值对应的文件夹中的每个图像。

我已经进行了一些研究,并且了解到,当涉及到静态图像时,最好从静态文件夹中导入它们,而不是将图像存储在数据库中,这是有道理的。是否有一种方法可以进行此映射并在Django中实现这一点?谢谢

稍后编辑

所以,我的settings.py如下所示:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

我的urls.py如下所示:

urlpatterns = [
    #其他URL
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)

上面的模型已根据foo-bar的答案进行了修改,并添加了@property构造函数:

class AreaMap(models.Model):
    Code = models.AutoField(primary_key=True)
    fCityCode = models.CharField(
        verbose_name='City', max_length=100)
    fCountyCode = models.CharField(
        verbose_name='County', max_length=100)
    fCountryCode = models.CharField(
        verbose_name='Country', max_length=100, default='RO')

    @property
    def img_url(self):
        return "{}{}".format(settings.MEDIA_URL, self.fCityCode)

使用浏览器的检查选项,这是照片的URL看起来像,但不知何故它在浏览器中没有显示:

<a href="/path/" class="card img-card fh-400 border-0 outer-bg" data-background-inner="/media/NewYork.jpg">
    <div class="inner-bg overlay-dark" style="background-image:url('/media/NewYork.jpg');">
    </div>
</a>

如果您有其他问题,请随时提出。

英文:

I have a Django app which has a model that holds cities, counties and countries codes:

models.py

class AreaMap(models.Model):
    Code = models.AutoField(primary_key=True)
    fCityCode = models.CharField(
        verbose_name=&#39;City&#39;, max_length=100)
    fCountyCode = models.CharField(
        verbose_name=&#39;County&#39;, max_length=100)
    fCountryCode = models.CharField(
        verbose_name=&#39;Country&#39;, max_length=100)

    def __str__(self):
        return self.fCityCode

For each city, I have some static images in my static folder which are not going to be changed (or at least, if required, the old file would be overwritten with a new one but keeping the same filename). The correspondence between the image and the value from the database is by field 'fCityCode`:

Example:

For New York - in the database is saved as 'NewYork' and the image filename from my static folder is the same, 'NewYork'.

Now, I would like to display in my HTML template every image from the folder that corresponds to a value from the database.

I've done some research and I read that when it comes to static images is better to import them from the static folder rather than storing the images in the database which makes sense. Is there any way of doing this mapping and achieving this using Django? Thanks

Later edit

So, my settings.py looks as below:

MEDIA_URL = &#39;/media/&#39;
MEDIA_ROOT = os.path.join(BASE_DIR, &#39;media/&#39;)

My urls.py looks as below:

urlpatterns = [
        #other urls
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)

The model above have been modified according to foo-bar answer and added the @property constructor:

class AreaMap(models.Model):
    Code = models.AutoField(primary_key=True)
    fCityCode = models.CharField(
        verbose_name=&#39;City&#39;, max_length=100)
    fCountyCode = models.CharField(
        verbose_name=&#39;County&#39;, max_length=100)
    fCountryCode = models.CharField(
        verbose_name=&#39;Country&#39;, max_length=100, default=&#39;RO&#39;)

    @property
    def img_url(self):
        return &quot;{}{}&quot;.format(settings.MEDIA_URL, self.fCityCode)

Using inspect option from the browser, this is how the URL of the photo looks like but somehow it is not displayed in the browser:

&lt;a href=&quot;/path/&quot; class=&quot;card img-card fh-400 border-0 outer-bg&quot; data-background-inner=&quot;/media/NewYork.jpg&quot;&gt;
&lt;div class=&quot;inner-bg overlay-dark&quot; style=&quot;background-image:url(&amp;quot;/media/NewYork.jpg&amp;quot;);&quot;&gt;
&lt;/div&gt;

答案1

得分: 1

根据您的设置,您的目录结构应如下所示:

.
├── project_root
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── media
│   └── foo
└── myapp_name
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    ├── migrations
    │   ├── 0001_initial.py
    │   └── __init__.py
    ├── models.py
    ├── templates
    │   └── sample.html
    ├── urls.py
    └── views.py

关键点是 media 目录应放在根目录中。

要在模板中呈现图像,您需要通过视图将 AreaMap 查询集传递给模板。

#myapp_name/views.py
from django.shortcuts import render


def sample_view(request):
    return render(request, 'sample.html', context={'qs': AreaMap.objects.all()})

然后在模板中迭代(或在模板中执行其他操作)查询集:

#myapp_name/templates/sample.html

{% for item in qs %}
    <p><img src="{{ item.img_url }}" width="300px"></p>
{% endfor %}
英文:

You are almost there !!
According to your settings, your directory structure should be like this,

.
├── project_root
│&#160;&#160; ├── settings.py
│&#160;&#160; ├── urls.py
│&#160;&#160; └── wsgi.py
├── manage.py
├── media
│&#160;&#160; └── foo
└── myapp_name
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    ├── migrations
    │&#160;&#160; ├── 0001_initial.py
    │&#160;&#160; └── __init__.py
    ├── models.py
    ├── templates
    │&#160;&#160; └── sample.html
    ├── urls.py
    └── views.py

Key Point is the media directory should be placed in the root director

To render the images in your template, you need to pass the AreaMap queryset to the template through view.

#myapp_name/views.py
from django.shortcuts import render


def sample_view(request):
    return render(request, &#39;sample.html&#39;, context={&#39;qs&#39;: AreaMap.objects.all()})

and now iterate (or whatever you want to do in your template) the Queryset in the template as,

#myapp_name/templates/sample.html

{% for item in qs %}
    &lt;p&gt;&lt;img src=&quot;{{ item.img_url }}&quot; width=&quot;300px&quot;&gt;&lt;/p&gt;
{% endfor %}

答案2

得分: 1

这些文件是固定的,不会经常更改,我认为它们应该存储在静态目录中。现在,如果文件夹结构如下:

.
├── project_root
├── static
│   ├── city_images
│      ├── LA.jpg
│      ├── NewYork.jpg
│      └── Washington.jpg
├── apps

那么您的设置应该如下:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]
STATIC_URL = '/static/'

然后只需使用:

{% load static %}
<div class="inner-bg overlay-dark" style="background-image:url({% static 'city_images/NewYork.jpg' %});">

或者您可以像在您的编辑中提到的那样与您的模型集成:

# 模型

from django.templatetags.static import static

class AreaMap(models.Model):
    Code = models.AutoField(primary_key=True)
    fCityCode = models.CharField(
        verbose_name='City', max_length=100)
    fCountyCode = models.CharField(
        verbose_name='County', max_length=100)
    fCountryCode = models.CharField(
        verbose_name='Country', max_length=100, default='RO')

    @property
    def img_url(self):
        return static("city_images/{}".format(self.fCityCode))

# 视图

{% for i in areamap_objects %}
   <img src="{{ i.img_url }}" >
{% endfor %}
英文:

As this files are fixed and won't be changed frequently, I think they should be stored in static directory. Now if the folder structure is like this:

.
├── project_root
├── static
│   ├── city_images
│      ├── LA.jpg
│      ├── NewYork.jpg
│      └── Washington.jpg
├── apps

Then your settings should be like this:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, &quot;static&quot;),
]
STATIC_URL = &#39;/static/&#39;

Then simply use:

{% load static %}
&lt;div class=&quot;inner-bg overlay-dark&quot; style=&quot;background-image:url({% static &#39;city_images/NewYork.jpg&#39; %};);&quot;&gt;

Or you can integrate with your model like mentioned in your edit:

# model

from django.templatetags.static import static

class AreaMap(models.Model):
    Code = models.AutoField(primary_key=True)
    fCityCode = models.CharField(
        verbose_name=&#39;City&#39;, max_length=100)
    fCountyCode = models.CharField(
        verbose_name=&#39;County&#39;, max_length=100)
    fCountryCode = models.CharField(
        verbose_name=&#39;Country&#39;, max_length=100, default=&#39;RO&#39;)

    @property
    def img_url(self):
        return static(&quot;city_images/{}&quot;.format(self.fCityCode))

# view

{% for i in areamap_objects %}
   &lt;img src=&quot;{{ i.img_url }}&quot; &gt;
{% endfor %}

huangapple
  • 本文由 发表于 2020年1月3日 22:53:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580683.html
匿名

发表评论

匿名网友

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

确定