【问题标题】:image isn't uploaded to media root using Django图像未使用 Django 上传到媒体根目录
【发布时间】:2015-10-04 07:56:58
【问题描述】:

我是 django 的新手,并试图解决这个问题,但找不到它有什么问题。表单的所有验证都完美通过,但图像实际上并没有上传到媒体根目录。我试图显示图像,但我只得到图像图标而不是图像。

设置根部分:

STATIC_ROOT = os.path.join(BASE_DIR, 'Vote','static')
STATIC_URL = '/static/'

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

型号代码:

class Vote(models.Model):
    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to= "images/vote/")
    rating = models.IntegerField(default=0)
    vote_type = models.ForeignKey(VoteType)

    def __unicode__(self):
        return self.name

views.py 创建(查看)代码:

def create(request):
    class RequiredFormSet(BaseFormSet):
        def __init__(self, *args, **kwargs):
            super(RequiredFormSet, self).__init__(*args, **kwargs)
            for form in self.forms:
                form.empty_permitted = False
    VoteFormSet = formset_factory(VoteForm, max_num=10, formset=RequiredFormSet)
    if request.method == 'POST': # If the form has been submitted...
        vote_list_form = VoteTypeForm(request.POST) # A form bound to the POST data
        vote_list_form.pub_date = timezone.now()
        # Create a formset from the submitted data
        vote_item_formset = VoteFormSet(request.POST, request.FILES)
        if vote_list_form.is_valid() and vote_item_formset.is_valid():
            vote_list = vote_list_form.save()
            for form in vote_item_formset.forms:
                vote_item = form.save(commit=False)
                vote_item.vote_type = vote_list
                print vote_item.vote_type
                vote_item.save()
            return HttpResponseRedirect('created/%s' %vote_list.id) # Redirect to a 'success' page
    else:
        vote_list_form = VoteTypeForm()
        vote_item_formset = VoteFormSet()
        vote_list_form.pub_date = timezone.now()

    c = {'vote_form': vote_list_form,
         'vote_item_formset': vote_item_formset,
        }
    c.update(csrf(request))

    return render_to_response('Vote/create.html', c)

还有模板代码(非常庞大,不确定是否需要):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
{% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static 'Vote/style.css' %}" />
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Dynamic Forms in Django Example</title>


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>

<script type="text/javascript">
$(document).ready(function() {
  // Code adapted from http://djangosnippets.org/snippets/1389/
  function updateElementIndex(el, prefix, ndx) {
    var id_regex = new RegExp('(' + prefix + '-\\d+-)');
    var replacement = prefix + '-' + ndx + '-';
    if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
 replacement));
    if (el.id) el.id = el.id.replace(id_regex, replacement);
    if (el.name) el.name = el.name.replace(id_regex, replacement);
  }
  function deleteForm(btn, prefix) {
    var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
    if (formCount > 1) {
      // Delete the item/form
      $(btn).parents('.item').remove();
      var forms = $('.item'); // Get all the forms
      // Update the total number of forms (1 less than before)
      $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
      var i = 0;
      // Go through the forms and set their indices, names and IDs
      for (formCount = forms.length; i < formCount; i++) {
        $(forms.get(i)).children().children().each(function() {
          updateElementIndex(this, prefix, i);
        });
      }
    } // End if
    else {
        alert("You have to enter at least one todo item!");
    }
    return false;
  }
  function addForm(btn, prefix) {
    var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
    // You can only submit a maximum of 10 todo items 
    if (formCount < 10) {
      // Clone a form (without event handlers) from the first form
      var row = $(".item:first").clone(false).get(0);
      // Insert it after the last form
      $(row).removeAttr('id').hide().insertAfter(".item:last").slideDown(300);

      // Remove the bits we don't want in the new row/form
      // e.g. error messages
      $(".errorlist", row).remove();
      $(row).children().removeClass('error');

      // Relabel/rename all the relevant bits
      $(row).children().children().each(function() {
        updateElementIndex(this, prefix, formCount);
        if ( $(this).attr('type') == 'text' )
          $(this).val('');
      });

      // Add an event handler for the delete item/form link 
      $(row).find('.delete').click(function() {
        return deleteForm(this, prefix);
      });
      // Update the total form count
      $('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1); 
    } // End if
    else {
      alert("Sorry, you can only enter a maximum of ten items.");
    }
    return false;
  }
  // Register the click event handlers
  $("#add").click(function() {
    return addForm(this, 'form');
  });

  $(".delete").click(function() {
    return deleteForm(this, 'form');
  });
});
</script>

</head>
<body>

<h1>Dynamic Forms in Django Example</h1>
<h2>Todo List</h2>

<form action="" method="POST" enctype="multipart/form-data">{% csrf_token %}
    <div class="section">
        {{ vote_form.as_p }}
    </div>

    <h2>Todo Items</h2>
    {{ vote_item_formset.management_form }}
    {% for form in vote_item_formset.forms %}
    <div class="item">
      {{ form.as_p }}
      <p style=""><a class="delete" href="#">Delete</a></p>
    </div>
    {% endfor %}

    <p><a id="add" href="#">Add another item</a></p>

    <input type="submit" value=" Submit " />

</form>

</body>
</html>

当我使用创建视图创建文件时,它不会将图像上传到媒体/图像/投票。为什么会这样?

编辑 1:添加了一些代码 有人还告诉我,我应该将其添加到我的代码中

 if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),
    )

现在的问题是当我尝试获取图像时,程序会在以下位置查找图像:

"GET /Vote/216/voting/images/vote/background_OeAkutY.gif/ HTTP/1.1" 404 3135

我认为他从我的 urls.py 文件中获取。但我不明白为什么程序在 /Vote/ID/voting... 而不是 MEDIA_ROOT。或者 GET 不代表它在看那个地方?

这是我的投票/urls.py:

urlpatterns = [
    #url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^$', views.index, name='index'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.results, name='results'),
    url(r'^(?P<pk>[0-9]+)/voting/$', views.voting, name='voting'),
    url(r'^create/$', views.create, name='create'),
    url(r'^create/created/(?P<pk>[0-9]+)/$', views.created, name='created'),
]

【问题讨论】:

    标签: python django image file-upload


    【解决方案1】:

    从 django.conf.urls.static 导入静态
    网址模式 = [
    url(r'^admin/', 包括(admin.site.urls)),
    url(r'', 包括('blog.urls')),

       ]
    

    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

    【讨论】:

    • 不,我没有添加。我应该在哪里添加它?我应该从哪里导入静态?我刚试过这个并得到错误 static() got an unexpected keyword argument 'document_root'
    • 嘿,你能评论我的回答吗?问题出在 MEDIA_ROOT,但网页仍然没有显示图像。
    【解决方案2】:

    我发现问题出在我的设置代码中。

    这里是固定代码:

    STATIC_ROOT = os.path.join(BASE_DIR, 'Vote','static')
    STATIC_URL = '/static/'
    
    MEDIA_ROOT = os.path.join(BASE_DIR,STATIC_ROOT,'media')
    MEDIA_URL = '/media/'
    

    现在它正在上传到正确的文件夹,但它没有在网页上显示,因为它正在寻找错误的位置。 -_- 无论如何谢谢你的帮助!

    当我尝试检查图像时:

    "GET /Vote/216/voting/images/vote/background_OeAkutY.gif/ HTTP/1.1" 404 3135
    

    但我不明白为什么它在 Vote/id-num/voting/images/vote/ 而不是媒体根目录中寻找图像。或者这只是网址,我在其他地方错了?对此表示赞赏。谢谢

    【讨论】:

    • 你能打印 media_root 的值吗
    • C:\Users\Vato\PycharmProjects\Project3\Vote\static\media
    【解决方案3】:

    您在媒体和静态之间感到困惑。希望这可以澄清问题:

    静态文件

    静态文件是作为应用程序的一部分提供的文件。

    STATIC_ROOTcollectstatic command 转储所有静态文件的位置,因此您可以将它们移动到生产网络服务器。

    你不需要在开发过程中与STATIC_ROOT 搞混。


    在您的情况下,您有一个应用程序 Vote,在其中您有一个 static 文件夹。这就是在开发期间提供静态文件所需的全部内容。您所要做的就是{% static 'folder/filename.ext' %} 其中 folder 是包含您的文件的静态文件夹。

    所以如果你的目录结构是:

    /Vote
     - __init__.py
     - migrations
     - admin.py
     - views.py
     - static
       - vote
         - images
           - foo.jpg
    

    你需要&lt;img src="{% static 'vote/images/foo.jpg' %}"&gt;

    媒体文件

    媒体文件是 django 所称的由应用程序用户上传的文件

    对于上传文件,您需要设置一个存储所有上传文件的位置。这个位置是父目录,它在整个项目中是通用的。对此的设置是MEDIA_ROOT。这应该是一个完整的系统文件路径

    假设你设置了MEDIA_ROOT = '/home/foo/bar/proj/media',并且在你的模型中你有:

    image = models.ImageField(upload_to='logos/')
    

    模型文件将上传到/home/foo/bar/proj/media/logos/

    要显示这些文件,你需要告诉 django 指向MEDIA_ROOT 目录的链接名称,这个设置是MEDIA_URL

    对于开发,你需要做三件事:

    1. MEDIA_URL设置为/media/

    2. Configure urls.py 提供媒体文件:

      urlpatterns = [
          # ... the rest of your URLconf goes here ...
      ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
      
    3. TEMPLATES 中将'django.template.context_processors.media' 添加到context_processors。这将在您的模板中激活{{ MEDIA_URL }}

    【讨论】:

    • 嘿,你能多谈谈最后一部分吗?第 3 部分。我不太明白你的意思。除了谢谢你的好答案
    • 我在settings.py中添加了代码,但是网页上仍然没有出现图片:(
    【解决方案4】:

    根据媒体文件的路径更改您的 MEDIA_ROOT:
    例如。 C:\Users\Vato\PycharmProjects\Project3\Vote\media

    【讨论】:

      猜你喜欢
      • 2019-07-04
      • 1970-01-01
      • 2021-03-09
      • 2021-11-03
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 2019-07-31
      相关资源
      最近更新 更多