简体   繁体   中英

How to get image from django form ImageField input

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,
                        )

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

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}}">

Do you want image to be visible before user actually clicks "submit" button of your form?

For that you probably should look into handling ajax requests.

If you want to simply show image on the page, eg you want to upload it, save it to your database, then take it's url from database and put it in template, you should just call for "url" attribute of an image field.

For example: You have model like:

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

and you already saved image in the database.

To pass it from database to template you should do something like that in your view :

p_image = ProductImage.objects.get(id=3)
context['product_image'] = p_image
return render (request, 'template.html', context)

And then in your template :

<img class="product-image" src="{{ product_image.image.url }}"/>

Actually, using Ajax it will be pretty much the same thing, only you should send your form and update page via javascript.

form: object = active_form(request.POST or None, request.FILES or None, instance=post)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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