Django: carga la imagen para formar

Soy nuevo en Django y estoy escribiendo mi primera aplicación. Es simple y usa un formulario para agregar un nuevo “cliente”. Uno de los campos es un ImageField, y luego de ingresar la imagen y enviar el formulario, la imagen desaparece y no está asociada con ese cliente.

He intentado meterme con la solicitud. ComandoFILES, pero nada parece funcionar, y he añadido enctype = “multipart / form-data” a la página html.

forms.py

from django import forms from django.contrib.auth.models import User from address_book.models import Client, UserProfile class ClientForm(forms.ModelForm): name = forms.CharField(max_length=128, help_text="Name: ") phone = forms.IntegerField(help_text="Phone Number: ") address = forms.CharField(max_length=128, help_text="Address: ", required=False) desired_weight = forms.IntegerField(help_text="Desired Weight: ") picture = forms.ImageField(help_text="Upload image: ", required=False) start_weight = forms.IntegerField(help_text="Start Weight: ") views = forms.IntegerField(widget=forms.HiddenInput(), initial=0) likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0) slug = forms.CharField(widget=forms.HiddenInput(), required=False) comments = forms.CharField(max_length=500, help_text="Comments: ", required=False) # An inline class to provide additional information on the form. class Meta: # Provide an association between the ModelForm and a model model = Client fields = ('name', 'phone', 'address', 'desired_weight', 'start_weight', 'picture',) class UserForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput()) class Meta: model = User fields = ('username', 'email', 'password') class UserProfileForm(forms.ModelForm): class Meta: model = UserProfile fields = ('nickname',) # fields = ('website', 'picture') 

views.py

 from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from address_book.forms import ClientForm, UserForm, UserProfileForm from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from address_book.models import Client def index(request): client_list = Client.objects.all().order_by('name') # Construct a dictionary to pass to the template engine as its context. # Note the key boldmessage is the same as {{ boldmessage }} in the template! context_dict = {'clients': client_list} # Return a rendered response to send to the client. # We make use of the shortcut function to make our lives easier. # Note that the first parameter is the template we wish to use. return render(request, 'address_book/index.html', context_dict) def add_client(request): # A HTTP POST? if request.method == 'POST': form = ClientForm(request.POST) # Have we been provided with a valid form? if form.is_valid(): # Save the new category to the database. form.save(commit=True) # Now call the index() view. # The user will be shown the homepage. if 'picture' in request.FILES: form.picture =request.FILES['picture'] form.save() return index(request) else: # The supplied form contained errors - just print them to the terminal. print form.errors else: # If the request was not a POST, display the form to enter details. form = ClientForm() # Bad form (or form details), no form supplied... # Render the form with error messages (if any). return render(request, 'address_book/add_client.html', {'form': form}) def client(request, client_name_slug): # Create a context dictionary which we can pass to the template rendering engine. context_dict = {} try: # Can we find a category name slug with the given name? # If we can't, the .get() method raises a DoesNotExist exception. # So the .get() method returns one model instance or raises an exception. client = Client.objects.get(slug=client_name_slug) context_dict['client_name'] = client.name context_dict['client_name_slug'] = client_name_slug context_dict['client_phone'] = client.phone context_dict['client_address'] = client.address context_dict['desired_weight'] = client.desired_weight context_dict['start_weight'] = client.start_weight context_dict['comments'] = client.comments context_dict['picture'] = client.picture # Retrieve all of the associated pages. # Note that filter returns >= 1 model instance. # pages = Page.objects.filter(category=category) # Adds our results list to the template context under name pages. # context_dict['pages'] = pages # We also add the category object from the database to the context dictionary. # We'll use this in the template to verify that the category exists. context_dict['client'] = client except Client.DoesNotExist: # We get here if we didn't find the specified category. # Don't do anything - the template displays the "no category" message for us. pass # Go render the response and return it to the client. print context_dict return render(request, 'address_book/client.html', context_dict) def register(request): # A boolean value for telling the template whether the registration was successful. # Set to False initially. Code changes value to True when registration succeeds. registered = False # If it's a HTTP POST, we're interested in processing form data. if request.method == 'POST': # Attempt to grab information from the raw form information. # Note that we make use of both UserForm and UserProfileForm. user_form = UserForm(data=request.POST) profile_form = UserProfileForm(data=request.POST) # If the two forms are valid... if user_form.is_valid() and profile_form.is_valid(): # Save the user's form data to the database. user = user_form.save() # Now we hash the password with the set_password method. # Once hashed, we can update the user object. user.set_password(user.password) user.save() # Now sort out the UserProfile instance. # Since we need to set the user attribute ourselves, we set commit=False. # This delays saving the model until we're ready to avoid integrity problems. profile = profile_form.save(commit=False) profile.user = user # Did the user provide a profile picture? # If so, we need to get it from the input form and put it in the UserProfile model. if 'picture' in request.FILES: profile.picture = request.FILES['picture'] # Now we save the UserProfile model instance. profile.save() # Update our variable to tell the template registration was successful. registered = True # Invalid form or forms - mistakes or something else? # Print problems to the terminal. # They'll also be shown to the user. else: print user_form.errors, profile_form.errors # Not a HTTP POST, so we render our form using two ModelForm instances. # These forms will be blank, ready for user input. else: user_form = UserForm() profile_form = UserProfileForm() # Render the template depending on the context. return render(request, 'address_book/register.html', {'user_form': user_form, 'profile_form': profile_form, 'registered': registered} ) def user_login(request): # If the request is a HTTP POST, try to pull out the relevant information. if request.method == 'POST': # Gather the username and password provided by the user. # This information is obtained from the login form. username = request.POST['username'] password = request.POST['password'] # Use Django's machinery to attempt to see if the username/password # combination is valid - a User object is returned if it is. user = authenticate(username=username, password=password) # If we have a User object, the details are correct. # If None (Python's way of representing the absence of a value), no user # with matching credentials was found. if user: # Is the account active? It could have been disabled. if user.is_active: # If the account is valid and active, we can log the user in. # We'll send the user back to the homepage. login(request, user) return HttpResponseRedirect('/address_book/') else: # An inactive account was used - no logging in! return HttpResponse("Your 3010 account is disabled.") else: # Bad login details were provided. So we can't log the user in. print "Invalid login details: {0}, {1}".format(username, password) return HttpResponse("Invalid login details supplied.") # The request is not a HTTP POST, so display the login form. # This scenario would most likely be a HTTP GET. else: # No context variables to pass to the template system, hence the # blank dictionary object... return render(request, 'address_book/login.html', {}) @login_required def user_logout(request): # Since we know the user is logged in, we can now just log them out. logout(request) # Take the user back to the homepage. return HttpResponseRedirect('/address_book/') 

models.py

 from django.db import models from django.template.defaultfilters import slugify from django.contrib.auth.models import User class Client(models.Model): name = models.CharField(max_length=128, unique=True) phone = models.IntegerField(default=0) desired_weight = models.IntegerField(default=0) start_weight = models.IntegerField(default=0) picture = models.ImageField(upload_to='/address_book/profile_pics', blank=True) address = models.CharField(max_length=128, blank=True) comments = models.CharField(max_length=500, blank=True) slug = models.SlugField(unique=True) def save(self, *args, **kwargs): self.slug = slugify(self.name) super(Client, self).save(*args, **kwargs) def __unicode__(self): return self.name class UserProfile(models.Model): # This line is required. Links UserProfile to a User model instance. user = models.OneToOneField(User) # The additional attributes we wish to include. # website = models.URLField(blank=True) nickname = models.CharField(max_length=20, blank=True) # picture = models.ImageField(upload_to='profile_images', blank=True) # Override the __unicode__() method to return out something meaningful! def __unicode__(self): return self.user.username 

add_client.html

 {% extends 'base.html' %} {% load staticfiles %} {% block title %}Add a Client{% endblock %} {% block body_block %} 

Add a Client

{% csrf_token %} {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {% for field in form.visible_fields %} {{ field.errors }} {{ field.help_text }} {{ field }}

{% endfor %}
{% endblock %}

client.html

 {% extends 'base.html' %} {% load staticfiles %} {% load easy_maps_tags %} {% load addressbook_extras %} {% block title %}{{ client_name }}{% endblock %} {% block body_block %} 

{{ client_name }}

  • Phone: {{ client_phone }}
  • Address: {{ client_address }}
  • Start Weight: {{ start_weight }}
  • Desired Weight: {{ desired_weight }}
  • Comments: {{ comments }}
  • {% if picture %} Client Photo {% else %}
  • No image uploaded
  • {% endif %} {% if client_address|address_test != None %} {% easy_map client_address 400 400 %} {% else %} Invalid address {% endif %} {% endblock %}

    base.html

         Address Book  {% if user.is_authenticated %} 

    Hello {{ user.username }}!

    {% else %}

    Please login below

    {% endif %} {% block body_block %}{% endblock %}

    Need to make changes?

    Tu error está aquí:

     Client Photo 

    Debe usar corchetes dobles y el método url() como en:

     Client Photo 

    ImageField s son FieldFile extendidos y puede acceder a la url relativa usando el método url ()

    Parece que olvidó pasar la solicitud. PELEAS a su formulario.

    Prueba esto :

      if request.method == 'POST': form = ClientForm(request.POST, request.FILES) 

    Aquí hay un excelente ejemplo de carga de archivos con django: Necesito un ejemplo mínimo de carga de archivos Django