图像未使用 Django 上传到媒体根目录
image isn't uploaded to media root using Django
我是 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>
当我使用创建视图创建文件时,它不会将图像上传到 media/images/vote。为什么会这样?
编辑1:added一些代码
有人还告诉我,我应该将其添加到我的代码中
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不代表在看那个地方?
这是我的Vote/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'),
]
从django.conf.urls.static导入静态
url模式=
[
url(r'^admin/', 包含(admin.site.urls)),
url(r'', 包括('blog.urls')),
]
url模式+=静态(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
url模式 += 静态(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
我发现问题出在我的设置代码中。
固定代码如下:
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/ 而不是媒体根目录中寻找图像。或者这只是 url 而我在其他地方错了?会对此发表评论。谢谢
您混淆了媒体和静态。希望这会澄清问题:
静态文件
静态文件是作为应用程序的一部分提供的文件。
STATIC_ROOT
是 collectstatic
command 将转储所有静态文件的位置,因此您可以将它们移动到生产 Web 服务器。
你不需要在开发过程中搞乱 STATIC_ROOT
。
在您的例子中,您有一个应用程序 Vote,并且在其中有一个 static 文件夹。这就是您在开发期间提供静态文件所需的全部内容。您所要做的就是 {% static 'folder/filename.ext' %}
,其中 folder 是包含您的文件的静态文件夹。
所以如果你的目录结构是:
/Vote
- __init__.py
- migrations
- admin.py
- views.py
- static
- vote
- images
- foo.jpg
你需要<img src="{% static 'vote/images/foo.jpg' %}">
媒体文件
媒体文件是 django 所称的由您的应用程序用户上传的文件
对于上传文件,您需要设置一个存储所有上传文件的位置。这个位置是父目录,它在整个项目中都是通用的。此设置为 MEDIA_ROOT
。这应该是一个完整的系统文件路径。
假设您设置 MEDIA_ROOT = '/home/foo/bar/proj/media'
,并且在您的模型中您有:
image = models.ImageField(upload_to='logos/')
模型的文件将上传到 /home/foo/bar/proj/media/logos/
。
要显示这些文件,需要告诉django一个link的名字,指向MEDIA_ROOT
目录,这个设置是MEDIA_URL
.
为了开发,你需要做三件事:
将MEDIA_URL
设置为/media/
Configure urls.py
提供媒体文件:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
将 'django.template.context_processors.media'
添加到 TEMPLATES
中的 context_processors
。这将在您的模板中激活 {{ MEDIA_URL }}
。
根据媒体文件的路径更改MEDIA_ROOT:
例如。 C:\Users\Vato\PycharmProjects\Project3\Vote\media
我是 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:added一些代码 有人还告诉我,我应该将其添加到我的代码中
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不代表在看那个地方?
这是我的Vote/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'),
]
从django.conf.urls.static导入静态
url模式=
[
url(r'^admin/', 包含(admin.site.urls)),
url(r'', 包括('blog.urls')),
]
url模式+=静态(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
url模式 += 静态(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
我发现问题出在我的设置代码中。
固定代码如下:
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/ 而不是媒体根目录中寻找图像。或者这只是 url 而我在其他地方错了?会对此发表评论。谢谢
您混淆了媒体和静态。希望这会澄清问题:
静态文件
静态文件是作为应用程序的一部分提供的文件。
STATIC_ROOT
是 collectstatic
command 将转储所有静态文件的位置,因此您可以将它们移动到生产 Web 服务器。
你不需要在开发过程中搞乱 STATIC_ROOT
。
在您的例子中,您有一个应用程序 Vote,并且在其中有一个 static 文件夹。这就是您在开发期间提供静态文件所需的全部内容。您所要做的就是 {% static 'folder/filename.ext' %}
,其中 folder 是包含您的文件的静态文件夹。
所以如果你的目录结构是:
/Vote
- __init__.py
- migrations
- admin.py
- views.py
- static
- vote
- images
- foo.jpg
你需要<img src="{% static 'vote/images/foo.jpg' %}">
媒体文件
媒体文件是 django 所称的由您的应用程序用户上传的文件
对于上传文件,您需要设置一个存储所有上传文件的位置。这个位置是父目录,它在整个项目中都是通用的。此设置为 MEDIA_ROOT
。这应该是一个完整的系统文件路径。
假设您设置 MEDIA_ROOT = '/home/foo/bar/proj/media'
,并且在您的模型中您有:
image = models.ImageField(upload_to='logos/')
模型的文件将上传到 /home/foo/bar/proj/media/logos/
。
要显示这些文件,需要告诉django一个link的名字,指向MEDIA_ROOT
目录,这个设置是MEDIA_URL
.
为了开发,你需要做三件事:
将
MEDIA_URL
设置为/media/
Configure
urls.py
提供媒体文件:urlpatterns = [ # ... the rest of your URLconf goes here ... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
将
'django.template.context_processors.media'
添加到TEMPLATES
中的context_processors
。这将在您的模板中激活{{ MEDIA_URL }}
。
根据媒体文件的路径更改MEDIA_ROOT:
例如。 C:\Users\Vato\PycharmProjects\Project3\Vote\media