简体   繁体   English

如何更新 Django 中的 ImageField?

[英]How to Update ImageField in Django?

i am new in Django.我是 Django 的新手。 i am having issue in updating ImageField.i have following code我在更新 ImageField 时遇到问题。我有以下代码

in models.py在模型.py

 class ImageModel(models.Model):
      image_name = models.CharField(max_length=50)
      image_color = models.CharField(max_length=50)
      image_document = models.ImageField(upload_to='product/')

-This is My forms.py -这是我的 forms.py

 class ImageForm(forms.ModelForm):
    class Meta:
        model = ImageModel
        fields = ['image_name', 'image_color' , 'image_document']

in Html file (editproduct.html)在 Html 文件 (editproduct.html)

<form method="POST" action="/myapp/updateimage/{{ singleimagedata.id }}">
       {% csrf_token %}
        <input class="form-control" type="text" name="image_name" value="{{ singleimagedata.image_name}}">
        <input class="form-control" type="file" name="image_document">
        <button type="submit" class="btn btn-primary">UPDATE PRODUCT</button>
</form>

-myapp is my application name. -myapp 是我的应用程序名称。 {{singleimagedata}} is a Variable Containing all fetched Data {{singleimagedata}} 是一个包含所有获取数据的变量

-urls.py -urls.py

urlpatterns = [
    path('productlist', views.productlist, name='productlist'),
    path('addproduct', views.addproduct, name='addproduct'),
    path('editimage/<int:id>', views.editimage, name='editimage'),
    path('updateimage/<int:id>', views.updateimage, name='updateimage'),
]

and Here is My views.py这是我的views.py

def productlist(request):
    if request.method == 'GET':
        imagedata = ImageModel.objects.all()
        return render(request,"product/productlist.html",{'imagedata':imagedata})

def addproduct(request):
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            messages.add_message(request, messages.SUCCESS, 'Image Uploaded')
            return redirect('/myapp/productlist')
    else:
        imageform = ImageForm()
        return render(request, "product/addproduct.html", {'imageform': imageform})

def editimage(request, id):
    singleimagedata = ImageModel.objects.get(id=id)
    return render(request, 'product/editproduct.html', {'singleimagedata': singleimagedata})

def updateimage(request, id):  #this function is called when update data
    data = ImageModel.objects.get(id=id)
    form = ImageForm(request.POST,request.FILES,instance = data)
    if form.is_valid():
        form.save()
        return redirect("/myapp/productlist")
    else:
        return render(request, 'demo/editproduct.html', {'singleimagedata': data})
  • My image Upload is working fine.i can not Update image while updating data.rest of the data are updated.i don't know how to update image and how to remove old image and put new image into directory.我的图像上传工作正常。我在更新数据时无法更新图像。数据的 rest 已更新。我不知道如何更新图像以及如何删除旧图像并将新图像放入目录。

I think you missed the enctype="multipart/form-data" , try to change:我认为您错过了enctype="multipart/form-data" ,请尝试更改:

<form method="POST" action="/myapp/updateimage/{{ singleimagedata.id }}">

into;进入;

<form method="POST" enctype="multipart/form-data" action="{% url 'updateimage' id=singleimagedata.id %}">

Don't miss also to add the image_color field to your html input.不要错过将image_color字段添加到您的html输入。
Because, in your case the image_color field model is designed as required field .因为,在您的情况下, image_color字段 model 被设计为required field

To remove & update the old image file from directory;从目录中删除和更新旧图像文件;

import os
from django.conf import settings

# your imported module...


def updateimage(request, id):  #this function is called when update data
    old_image = ImageModel.objects.get(id=id)
    form = ImageForm(request.POST, request.FILES, instance=old_image)

    if form.is_valid():

        # deleting old uploaded image.
        image_path = old_image.image_document.path
        if os.path.exists(image_path):
            os.remove(image_path)

        # the `form.save` will also update your newest image & path.
        form.save()
        return redirect("/myapp/productlist")
    else:
        context = {'singleimagedata': old_image, 'form': form}
        return render(request, 'demo/editproduct.html', context)

I had a similar issue while updating the profile_pic of user.我在更新用户的 profile_pic 时遇到了类似的问题。 I solved this with the following code I think this might help:我用以下代码解决了这个问题,我认为这可能会有所帮助:

Models.py模型.py

class Profile(models.Model):
    # setting o2o field of user with User model
    user_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True)
    first_name = models.CharField(max_length=70, null=True, blank=True)
    last_name = models.CharField(max_length=70, null=True, blank=True)    
    profile_pic = models.ImageField(upload_to="images", blank=True, null=True,)


    def __str__(self):
        return str(self.user_name)

forms.py forms.py

class ProfileEditForm(ModelForm):
    class Meta:
        model = Profile
        fields = '__all__'
        # excluding user_name as it is a one_to_one relationship with User model
        exclude = ['user_name']

views.py视图.py

@login_required(login_url='login')
def edit_profile(request, id):
    username = get_object_or_404(Profile, id=id)
    extended_pro_edit_form = ProfileEditForm(instance=username)
    if request.method == "POST":
        extended_pro_edit_form = ProfileEditForm(request.POST, request.FILES, instance=username)
        if extended_pro_edit_form.is_valid():
            extended_pro_edit_form.save()
            next_ = request.POST.get('next', '/')
            return HttpResponseRedirect(next_)

    context = {'extended_pro_edit_form': extended_pro_edit_form}
    return render(request, 'edit_profile.html', context)

edit-profile.html编辑配置文件.html

<form action="" method="post"
              enctype="multipart/form-data">
            {% csrf_token %}
            {{ extended_pro_edit_form.as_p }}
            {{ extended_pro_edit_form.errors }}
            <!--To redirect user to prvious page after post req-->
            <input type="hidden" name="next" value="{{ request.GET.next }}">

            <button type="submit">UPDATE</button>

        </form>

Answer from @binpy should solve your problem. @binpy 的回答应该可以解决您的问题。 In addition to your second answer, you could do:除了你的第二个答案,你可以这样做:

def updateimage(request, id):  #this function is called when update data
    data = ImageModel.objects.get(id=id)
    form = ImageForm(request.POST,request.FILES,instance = data)
    if form.is_valid():
        data.image_document.delete()  # This will delete your old image
        form.save()
        return redirect("/myapp/productlist")
    else:
        return render(request, 'demo/editproduct.html', {'singleimagedata': data})

Check delete() method on django docs.检查 django 文档上的delete()方法。

some times something like cached old image is not replaced in the front-end so you might just need to forces refresh by pressing CTRL + F5 or clear your browsing history.有时不会在前端替换缓存的旧图像之类的东西,因此您可能只需要通过按CTRL + F5强制刷新或清除浏览历史记录。

the answer given by @binpy is a needed update so that the files are passed to the back-end. @binpy 给出的答案是需要更新,以便将文件传递到后端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM