当我尝试将用户上传的图像保存在视图中时,为啥 ImageField 中的 upload_to 根本不起作用
Posted
技术标签:
【中文标题】当我尝试将用户上传的图像保存在视图中时,为啥 ImageField 中的 upload_to 根本不起作用【英文标题】:Why does upload_to in ImageField not working at all when i try to save uploaded image from user in views当我尝试将用户上传的图像保存在视图中时,为什么 ImageField 中的 upload_to 根本不起作用 【发布时间】:2021-12-19 19:40:39 【问题描述】:我正在尝试用非常简单的架构项目制作一个简单的邮件服务。此时我的后端部分开发几乎完成了,但我已经停止了两天,因为我不知道为什么图像保存不起作用。
显然,我希望用户上传他的个人资料头像,并将其保存到我在 upload_to 中设置的路径。 图片路径必须类似于profiles/UserName/his_profile_img.jpeg
在过去的两天里,我花了超过 12 个小时试图解决它。
-
这是我的模型 ImageField 哪里出了问题:
from django.db import models
from datetime import datetime, timedelta
from django.contrib.auth.models import User
def username(user, file):
string_username = str(user).split()[0]
return f"profiles/string_username/file"
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="Profile")
##### This is here
avatar = models.ImageField(default="/profiles/profile.png", upload_to=username)
name = models.CharField(max_length=30, blank=True)
surname = models.CharField(max_length=30, blank=True)
email = models.EmailField(max_length=64, blank=True)
bio = models.CharField(max_length=1024, blank=True)
def username(self):
return self.user.username
@property
def joined(self):
joined = self.user.date_joined.strftime("%d %B %Y")
is_today = joined == datetime.today().strftime("%d %B %Y")
if is_today:
return "today"
is_yesterday = joined == datetime.date(datetime.today() - timedelta(days=1)).strftime("%d %B %Y")
if is_yesterday:
return "yesterday"
return f"joined"
def __str__(self):
return f"self.user profile"
-
这是一个视图函数,不保存图像:
def my_profile(request):
if not request.user.is_authenticated:
return redirect('login')
user_profile = Profile.objects.get(user=request.user)
sent_messages = Mail.objects.filter(from_user_inf=request.user).count()
received_messages = Mail.objects.filter(to_user_inf=request.user).count()
context =
"profile": user_profile,
"sent": sent_messages,
"received": received_messages
if request.method == 'POST':
user_profile.name = request.POST.get("name")
user_profile.surname = request.POST.get("surname")
user_profile.email = request.POST.get("email")
user_profile.bio = request.POST.get("bio")
avatar = request.FILES.get("avatar")
# I've also tried get image by:
##### request.POST.get("avatar")
##### saving image by "with open" command(this is too weird)
if avatar:
user_profile.avatar = avatar
user_profile.save()
messages.info(request, "Saved successfully !")
return render(request, 'my_profile.html', context=context)
return render(request, 'my_profile.html', context=context)
-
还有 my_profile.html 文件和我设置图片上传的一段代码:
<div>
<img class="img" src=" profile.avatar.url " >
<label for="file" cursor="pointer" class="btn">Change Photo</label>
<input id="file" style="visibility:hidden;" name="avatar" type="file" accept="image/*">
</div>
是的,我做了正确的设置并将其添加到网址中。
-
settings.py ---> ROOT 和 URL 媒体,静态设置:
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
-
urls.py:
urlpatterns = [
### There are my urls
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
感谢关注,希望能解决!
【问题讨论】:
【参考方案1】:ModelForms
很容易:
# forms.py
from django import forms
# import your model here
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('name', 'surname', 'email', 'bio', 'avatar')
# views.py
# imports...
def my_profile(request):
if not request.user.is_authenticated:
return redirect('login')
user_profile = Profile.objects.get(user=request.user)
sent_messages = Mail.objects.filter(from_user_inf=request.user).count()
received_messages = Mail.objects.filter(to_user_inf=request.user).count()
context =
"profile": user_profile,
"sent": sent_messages,
"received": received_messages
if request.method == 'POST':
form = ProfileForm(
instance=user_profile, data=request.POST, files=request.FILES
)
if form.is_valid():
form.save()
messages.info(request, "Saved successfully !")
# Best use a redirect to a success page here.
# Otherwise, if the user clicks reload, the form will be resent.
return render(request, 'my_profile.html', context=context)
else:
form = ProfileForm(instance=user_profile)
# Use the form in the template! @see: https://docs.djangoproject.com/en/3.2/topics/forms/#the-template
# If you need personalize for bootstrap, etc @see: https://github.com/django-crispy-forms/django-crispy-forms
context['form'] = form
return render(request, 'my_profile.html', context=context)
如果您需要上传不带ModelForm
的文件,请手动将文件保存到服务器路径,然后在模型中设置此路径(相对于MEDIA_ROOT)。请参阅此链接中的handle_uploaded_file
https://docs.djangoproject.com/en/3.2/topics/http/file-uploads/#basic-file-uploads。
【讨论】:
它不起作用...这是相同的结果。图片未保存 我们可以在任何社交媒体平台上找到彼此吗?我真的需要帮助,我很困惑,它不起作用 @proghb,我在 github 上上传了一个最小的 Django 3 示例:github.com/t-cc/django-uploads-example。希望对你有帮助。以上是关于当我尝试将用户上传的图像保存在视图中时,为啥 ImageField 中的 upload_to 根本不起作用的主要内容,如果未能解决你的问题,请参考以下文章
当图像保存在核心数据的集合视图中时,应用程序因内存错误而崩溃