我正在尝试在我的 Django 项目上实现图像上传功能,但没有创建文件。我的代码有什么问题?
I am trying to implement an image upload feature on my Django project but no file is being created. What is wrong with my code?
我有一个个人资料页面,其中包含默认个人资料图片和旁边的 'Change' 按钮,单击该按钮将触发模式。在此模式中,图像上传按钮(用于选择图像)将与提交按钮一起出现。我创建了一个单独的视图来处理图像上传。我不知道为什么上传后没有创建文件。 Django 没有给出错误消息。我怀疑它与 settings.py 配置或我的模态字段的操作部分有关。
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from .forms import KeyForm, Weekly_Item_Form, Daily_Item_Form, ProfileForm
from .models import Key, Weekly_Item, Daily_Item, Profile
def profile_view(request):
profiles = Profile.objects.all()
mainprofile = profiles.last()
if profiles:
form = ProfileForm()
context = {
'page_title':"Profile",
'mainprofile':mainprofile,
'form': form
}
else:
context = {'page_title':"Profile"}
return render(request, "bujo/profile.html", context)
def update_image(request, pk):
mainprofile = Profile.objects.get(id=pk)
form = ProfileForm(instance=mainprofile)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=mainprofile)
if form.is_valid():
form.save()
return redirect('profile')
return redirect('profile')
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('profile/', app_views.profile_view, name='profile'),
path('update_image/<str:pk>', app_views.update_image, name='update_image'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
profile.html
<form method='POST' enctype="multipart/form-data" action="{% url 'update_image' mainprofile.pk %}"> {% csrf_token %}
{{ form.image }}
<input type='submit' class="btn btn-primary"" value='Change profile picture' />
</form>
forms.py
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['name', 'image', 'nickname', 'bio']
models.py
class Profile(models.Model):
name = models.CharField(max_length=50, blank=False)
image = models.ImageField(null=True, blank=True, upload_to="images/")
nickname = models.CharField(max_length=20, null=False, blank=True)
bio = models.CharField(max_length=100, null=False, blank=True)
您的表单也有图像以外的字段。您不在模板中呈现它们,但表单 class 需要它们,因此当提交表单时,它被认为是无效的。如果您只想更新图像,请创建另一个只有图像字段的表单 class。
在您的 forms.py
中添加另一个表格 class:
from django import forms
from .models import Profile
class ProfileImageForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
在您看来:
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from .forms import KeyForm, Weekly_Item_Form, Daily_Item_Form, ProfileForm, ProfileImageForm
from .models import Key, Weekly_Item, Daily_Item, Profile
def profile_view(request):
profiles = Profile.objects.all()
mainprofile = profiles.last() # This line feels weird! You always make the form for the last profile only.
if profiles:
form = ProfileImageForm()
context = {
'page_title':"Profile",
'mainprofile':mainprofile,
'form': form
}
else:
context = {'page_title':"Profile"}
return render(request, "bujo/profile.html", context)
def update_image(request, pk):
mainprofile = Profile.objects.get(id=pk)
form = ProfileImageForm(instance=mainprofile)
if request.method == 'POST':
form = ProfileImageForm(request.POST, request.FILES, instance=mainprofile)
if form.is_valid():
form.save()
return redirect('profile')
return redirect('profile')
我有一个个人资料页面,其中包含默认个人资料图片和旁边的 'Change' 按钮,单击该按钮将触发模式。在此模式中,图像上传按钮(用于选择图像)将与提交按钮一起出现。我创建了一个单独的视图来处理图像上传。我不知道为什么上传后没有创建文件。 Django 没有给出错误消息。我怀疑它与 settings.py 配置或我的模态字段的操作部分有关。
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from .forms import KeyForm, Weekly_Item_Form, Daily_Item_Form, ProfileForm
from .models import Key, Weekly_Item, Daily_Item, Profile
def profile_view(request):
profiles = Profile.objects.all()
mainprofile = profiles.last()
if profiles:
form = ProfileForm()
context = {
'page_title':"Profile",
'mainprofile':mainprofile,
'form': form
}
else:
context = {'page_title':"Profile"}
return render(request, "bujo/profile.html", context)
def update_image(request, pk):
mainprofile = Profile.objects.get(id=pk)
form = ProfileForm(instance=mainprofile)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=mainprofile)
if form.is_valid():
form.save()
return redirect('profile')
return redirect('profile')
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('profile/', app_views.profile_view, name='profile'),
path('update_image/<str:pk>', app_views.update_image, name='update_image'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
profile.html
<form method='POST' enctype="multipart/form-data" action="{% url 'update_image' mainprofile.pk %}"> {% csrf_token %}
{{ form.image }}
<input type='submit' class="btn btn-primary"" value='Change profile picture' />
</form>
forms.py
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['name', 'image', 'nickname', 'bio']
models.py
class Profile(models.Model):
name = models.CharField(max_length=50, blank=False)
image = models.ImageField(null=True, blank=True, upload_to="images/")
nickname = models.CharField(max_length=20, null=False, blank=True)
bio = models.CharField(max_length=100, null=False, blank=True)
您的表单也有图像以外的字段。您不在模板中呈现它们,但表单 class 需要它们,因此当提交表单时,它被认为是无效的。如果您只想更新图像,请创建另一个只有图像字段的表单 class。
在您的 forms.py
中添加另一个表格 class:
from django import forms
from .models import Profile
class ProfileImageForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
在您看来:
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from .forms import KeyForm, Weekly_Item_Form, Daily_Item_Form, ProfileForm, ProfileImageForm
from .models import Key, Weekly_Item, Daily_Item, Profile
def profile_view(request):
profiles = Profile.objects.all()
mainprofile = profiles.last() # This line feels weird! You always make the form for the last profile only.
if profiles:
form = ProfileImageForm()
context = {
'page_title':"Profile",
'mainprofile':mainprofile,
'form': form
}
else:
context = {'page_title':"Profile"}
return render(request, "bujo/profile.html", context)
def update_image(request, pk):
mainprofile = Profile.objects.get(id=pk)
form = ProfileImageForm(instance=mainprofile)
if request.method == 'POST':
form = ProfileImageForm(request.POST, request.FILES, instance=mainprofile)
if form.is_valid():
form.save()
return redirect('profile')
return redirect('profile')