替代 Django 的 image.url 方法?
Alternative to Django's image.url method?
我正在使用内联表单集,以便用户可以一次上传多张图片。图像已保存并且功能符合预期,但前端除外。当我使用类似于 {{ form. image }},我可以清楚地看到我的图像已保存,当我单击 url 时,我将被重定向到上传的文件。问题似乎是当我尝试将图像的 URL 设置为图像元素的 src 时,没有存储 absoulte url。
尝试在 <p>
标签中记录 MEDIA_URL 和 MEDIA_ROOT 没有结果。
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
ROOT_URLCONF = 'dashboard_app.urls'
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
urls.py
from django.conf.urls import url, include
from . import views
from django.conf.urls.static import static
from django.conf import settings
app_name = 'Accounts_Namespace'
urlpatterns = [
url(r'^$', views.Register, name='Accounts_Register'),
url(r'^change-password/$', views.ChangePassword, name="Accounts_Change_Password"),
url(r'^login/$', views.Login, name='Accounts_Login'),
url(r'^logout/$', views.Logout, name='Accounts_Logout'),
url(r'^profile/$', views.ViewProfile, name='Accounts_View_Profile'),
url(r'^profile/edit/$', views.EditProfile, name="Accounts_Edit_Profile"),
url(r'^school/', include('student_map_app.urls', namespace="Student_Maps_Namespace")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
class Gallery(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
image = models.ImageField(upload_to="gallery_images")
uploaded = models.DateTimeField(auto_now_add=True)
views.py
def EditProfile(request):
user = request.user
galleryInlineFormSet = inlineformset_factory(get_user_model(), Gallery, form=GalleryForm)
selectedUserGallery = Gallery.objects.filter(user=user).order_by('uploaded')
userGallery_initial = [{'image': selection.image} for selection in selectedUserGallery] # Using this syntax because formset initials accept dictionaries
if request.method == "POST":
profile_form = ProfileEditForm(request.POST, instance=request.user)
gallery_inlineformset = galleryInlineFormSet(request.POST, request.FILES) # Essentially, we're passing a queryset
if profile_form.is_valid() and gallery_inlineformset.is_valid():
# Altering the User model through the UserProfile model's UserProfileForm representative
user.first_name = profile_form.cleaned_data['first_name']
user.last_name = profile_form.cleaned_data['last_name']
user.save()
new_images = []
for gallery_form in gallery_inlineformset:
image = gallery_form.cleaned_data.get('image')
if image:
new_images.append(Gallery(user=user, image=image))
try:
Gallery.objects.filter(user=user).delete()
Gallery.objects.bulk_create(new_images)
messages.success(request, 'You have updated your profile.')
except IntegrityError:
messages.error(request, 'There was an error saving your profile.')
return HttpResponseRedirect('https://www.youtube.com')
else:
profile_form = ProfileEditForm(request.user)
gallery_inlineformset = galleryInlineFormSet(initial=userGallery_initial)
args = { 'profile_form':profile_form, 'gallery_inlineformset':gallery_inlineformset }
return render(request, 'accounts_app/editprofile.html', args)
editprofile.html
{% block main %}
<section class="Container">
<section class="Main-Content">
<form id="post_form" method="POST" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ gallery_inlineformset.management_form }}
{% for gallery_form in gallery_inlineformset %}
<div class="link-formset">
{{ gallery_form.image }} <!-- Show the image upload field -->
<p>{{ MEDIA_ROOT }}</p>
<p>{{ MEDIA_URL }}</p>
<img src="/media/{{gallery_form.image.image.url}}">
</div>
{% endfor %}
<input type="submit" name="submit" value="Submit" />
</form>
</section>
</section>
{% endblock %}
再一次,当我尝试时:
<img src="{{ MEDIA_URL }}{{ gallery_form.image.url }}">
我得到一个值 "unknown" 作为源,但我可以单击“{{ gallery_form.image}}”生成的 link 并查看上传的图像。尝试同时记录 "MEDIA_URL" 和 "MEDIA_ROOT" 不会产生任何结果。不太确定问题出在哪里。
使用 <img src="{{ gallery_form.image.url }}">
并确保 image
不是 None
将此行添加到您的 urls.py
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
无需在图片地址前添加{{MEDIA_URL}}
。因为默认情况下它会在您的图像 url 路径之前添加 /media
。
还要确保将所有从 media
开始的路径添加到您的 url。
from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
当尝试在 django 模板中打印图像时 url,处理图像不存在的情况,如下所示:
<img src="{% if gallery_form.image %}{{ gallery_form.image.url }}{%else%} <default-image-path-here> {%endif%}"
虽然我不明白为什么我不能使用 Django 预定义的 .url() 方法,但是我确实使用了之前用户向我建议的另一种解决方案我的问题。基本上,在用户上传图片并将它们存储在数据库中之后,我们创建一个变量来存储这些图片的 URL 属性,并从模板中访问该变量。它看起来像这样:
views.py
selectedUserGallery = Gallery.objects.filter(user=user) # Get gallery objects where user is request.user
userGallery_initial = [{'image': selection.image, 'image_url':selection.image.url} for selection in selectedUserGallery if selection.image]
if request.method == "GET":
print("--------GET REQUEST: PRESENTING PRE-EXISTING GALLERY IMAGES.-------")
profile_form = ProfileEditForm(request.user)
gallery_inlineformset = galleryInlineFormSet(initial=userGallery_initial)
template.html
<form id="post_form" method="POST" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ gallery_inlineformset.management_form }}
{% for gallery_form in gallery_inlineformset %}
<div class="link-formset">
{{ gallery_form.image }} <!-- Show the image upload field, this is not he image var from views.py -->
{% if gallery_form.image is not None %}
<p>The image should be below:</p>
<img src="{{ gallery_form.initial.image_url }}">
{% endif %}
</div>
{% endfor %}
<input type="submit" name="gallery-submit" value="Submit" />
</form>
此外,我最终替换了原始 post 中的大部分代码,因为我不再使用 bulk_create()。
我正在使用内联表单集,以便用户可以一次上传多张图片。图像已保存并且功能符合预期,但前端除外。当我使用类似于 {{ form. image }},我可以清楚地看到我的图像已保存,当我单击 url 时,我将被重定向到上传的文件。问题似乎是当我尝试将图像的 URL 设置为图像元素的 src 时,没有存储 absoulte url。
尝试在 <p>
标签中记录 MEDIA_URL 和 MEDIA_ROOT 没有结果。
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
ROOT_URLCONF = 'dashboard_app.urls'
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
urls.py
from django.conf.urls import url, include
from . import views
from django.conf.urls.static import static
from django.conf import settings
app_name = 'Accounts_Namespace'
urlpatterns = [
url(r'^$', views.Register, name='Accounts_Register'),
url(r'^change-password/$', views.ChangePassword, name="Accounts_Change_Password"),
url(r'^login/$', views.Login, name='Accounts_Login'),
url(r'^logout/$', views.Logout, name='Accounts_Logout'),
url(r'^profile/$', views.ViewProfile, name='Accounts_View_Profile'),
url(r'^profile/edit/$', views.EditProfile, name="Accounts_Edit_Profile"),
url(r'^school/', include('student_map_app.urls', namespace="Student_Maps_Namespace")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
class Gallery(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
image = models.ImageField(upload_to="gallery_images")
uploaded = models.DateTimeField(auto_now_add=True)
views.py
def EditProfile(request):
user = request.user
galleryInlineFormSet = inlineformset_factory(get_user_model(), Gallery, form=GalleryForm)
selectedUserGallery = Gallery.objects.filter(user=user).order_by('uploaded')
userGallery_initial = [{'image': selection.image} for selection in selectedUserGallery] # Using this syntax because formset initials accept dictionaries
if request.method == "POST":
profile_form = ProfileEditForm(request.POST, instance=request.user)
gallery_inlineformset = galleryInlineFormSet(request.POST, request.FILES) # Essentially, we're passing a queryset
if profile_form.is_valid() and gallery_inlineformset.is_valid():
# Altering the User model through the UserProfile model's UserProfileForm representative
user.first_name = profile_form.cleaned_data['first_name']
user.last_name = profile_form.cleaned_data['last_name']
user.save()
new_images = []
for gallery_form in gallery_inlineformset:
image = gallery_form.cleaned_data.get('image')
if image:
new_images.append(Gallery(user=user, image=image))
try:
Gallery.objects.filter(user=user).delete()
Gallery.objects.bulk_create(new_images)
messages.success(request, 'You have updated your profile.')
except IntegrityError:
messages.error(request, 'There was an error saving your profile.')
return HttpResponseRedirect('https://www.youtube.com')
else:
profile_form = ProfileEditForm(request.user)
gallery_inlineformset = galleryInlineFormSet(initial=userGallery_initial)
args = { 'profile_form':profile_form, 'gallery_inlineformset':gallery_inlineformset }
return render(request, 'accounts_app/editprofile.html', args)
editprofile.html
{% block main %}
<section class="Container">
<section class="Main-Content">
<form id="post_form" method="POST" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ gallery_inlineformset.management_form }}
{% for gallery_form in gallery_inlineformset %}
<div class="link-formset">
{{ gallery_form.image }} <!-- Show the image upload field -->
<p>{{ MEDIA_ROOT }}</p>
<p>{{ MEDIA_URL }}</p>
<img src="/media/{{gallery_form.image.image.url}}">
</div>
{% endfor %}
<input type="submit" name="submit" value="Submit" />
</form>
</section>
</section>
{% endblock %}
再一次,当我尝试时:
<img src="{{ MEDIA_URL }}{{ gallery_form.image.url }}">
我得到一个值 "unknown" 作为源,但我可以单击“{{ gallery_form.image}}”生成的 link 并查看上传的图像。尝试同时记录 "MEDIA_URL" 和 "MEDIA_ROOT" 不会产生任何结果。不太确定问题出在哪里。
使用 <img src="{{ gallery_form.image.url }}">
并确保 image
不是 None
将此行添加到您的 urls.py
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
无需在图片地址前添加{{MEDIA_URL}}
。因为默认情况下它会在您的图像 url 路径之前添加 /media
。
还要确保将所有从 media
开始的路径添加到您的 url。
from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
当尝试在 django 模板中打印图像时 url,处理图像不存在的情况,如下所示:
<img src="{% if gallery_form.image %}{{ gallery_form.image.url }}{%else%} <default-image-path-here> {%endif%}"
虽然我不明白为什么我不能使用 Django 预定义的 .url() 方法,但是我确实使用了之前用户向我建议的另一种解决方案我的问题。基本上,在用户上传图片并将它们存储在数据库中之后,我们创建一个变量来存储这些图片的 URL 属性,并从模板中访问该变量。它看起来像这样:
views.py
selectedUserGallery = Gallery.objects.filter(user=user) # Get gallery objects where user is request.user
userGallery_initial = [{'image': selection.image, 'image_url':selection.image.url} for selection in selectedUserGallery if selection.image]
if request.method == "GET":
print("--------GET REQUEST: PRESENTING PRE-EXISTING GALLERY IMAGES.-------")
profile_form = ProfileEditForm(request.user)
gallery_inlineformset = galleryInlineFormSet(initial=userGallery_initial)
template.html
<form id="post_form" method="POST" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ gallery_inlineformset.management_form }}
{% for gallery_form in gallery_inlineformset %}
<div class="link-formset">
{{ gallery_form.image }} <!-- Show the image upload field, this is not he image var from views.py -->
{% if gallery_form.image is not None %}
<p>The image should be below:</p>
<img src="{{ gallery_form.initial.image_url }}">
{% endif %}
</div>
{% endfor %}
<input type="submit" name="gallery-submit" value="Submit" />
</form>
此外,我最终替换了原始 post 中的大部分代码,因为我不再使用 bulk_create()。