Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get image from django form ImageField input

Tags:

python

django

I'm trying to get an image from a input ImageFile to display in the template and also save that ImageFile to the models ImageField.

The code below spits out an error:

upload_img_temp.write(uploaded_image)
TypeError: a bytes-like object is required, not 'str'

Form

class UploadImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['image']

View

def uploadImageView(request):
    form = UploadImageForm(request.POST or None, request.FILES or None)
    if request.method == 'POST':
        if form.is_valid:
            request.session['image'] = request.POST['image']
            return redirect('image:create')

def imageCreateView(request):
    uploaded_image = request.session.get('image')
    upload_img_temp = NamedTemporaryFile()
    upload_img_temp.write(uploaded_image)
    upload_img_temp.flush()

    form_create = ImageModelCreateForm(request.POST or None, request.FILES or None,)

    if form_create.is_valid():
        instance = form_create.save(commit=False)
        instance.image = upload_img_temp

Template

<img class="image" src="{{ upload_img_temp }}">

  <form method="POST" action="">
    {% csrf_token %}
    <input type="submit"></input>
    {{ form }}
  </form>

Model

def upload_location(instance, filename):
    filebase, extension = filename.split(".")
    return "%s/%s.%s" %('picx', uuid.uuid4(), extension)

class Image(models.Model):
    image           = models.ImageField(
                        upload_to=upload_location,
                        null=False,
                        blank=False,
                        )
like image 337
lolz Avatar asked Oct 27 '25 03:10

lolz


2 Answers

So you have multiple problems.

  1. <form method="POST" action="" enctype='multipart/form-data' >

You need to add enctype='multipart/form-data' in the form otherwise no file will be accepted.

  1. To display the Image you would need something like <img class="image" src="{{Image.image.url}}"> Note that "Image" needs to be a valid arguments you defined in your views.py context part for this template. Its a reference to your model and the second "image" keyword refers to your model attribute "image". .url is required.
  2. Change your views.py to something similar:

    def uploadG(request):
      form = PostForm(request.POST or None, request.FILES or None)
      if form.is_valid():
        print ("form was valid TEST") #controll your console and check if that statement appears when you click upload.
        instance = form.save(commit = False)
        ....
        instance.save()
        messages.success(request, 'You uploaded it')
    

Hope that helped. If not leave a comment

like image 124
hansTheFranz Avatar answered Oct 28 '25 19:10

hansTheFranz


There may be many possibilties for the error. Firstly you need to make sure you specify upload_to attributes in quotes like upload_to='images'

class ProductImage(models.Model):
    image = models.ImageField(
               upload_to='images',
               null=False,
               blank=False,
              )

which will create a folder named images under the media folder and place image within this images folder. Second you need to make sure that you add enctype='multipart/form-data' inside tag as

<img class="image" src="{{ upload_img_temp }}">

  <form method="POST" action="">
    {% csrf_token %}
    <input type="submit"></input>
    {{ form }}
  </form>

Third instead of saving image to session you can simply save that image to your model class as model instance by saying

def uploadImageView(request):

    def uploadImageView(request):
        form = UploadImageForm(request.POST or None, request.FILES or None)
        if request.method == 'POST':
            if form.is_valid:
                form.save()
                context['form']=form
                return render(request, 'your_file_name.html', 
                {'context':context}
                )

and accessing that image instance in your template by setting img url as

<img url="{{form.image.url}}">
like image 20
azeem_pdd Avatar answered Oct 28 '25 19:10

azeem_pdd