1

I'm new to django and want to make a form that allows a user to select one of three images using radio boxes, once the user selects the image it is saved to their profile and displayed on their profile page.

I am using: django 1.8.3 userena 1.4.1

Any help or links to documentation that will help would be great.

Blezx
  • 614
  • 2
  • 6
  • 19
  • Try to use django form to represent your choices. https://docs.djangoproject.com/en/1.8/topics/forms/ – Shang Wang Aug 11 '15 at 17:39
  • Yea that's what I have been doing I can make the form and every thing but I get stuck at making the submit save the selected image to the users profile. – Blezx Aug 11 '15 at 17:43
  • post you forms.py and views.py code. Where do you stuck ? – Rajesh Kaushik Aug 11 '15 at 17:48
  • Here's a complete example. https://coderwall.com/p/bz0sng/simple-django-image-upload-to-model-imagefield. But you should do some of your own research and be more specific about your problem. – Shang Wang Aug 11 '15 at 17:49
  • I have done my own research and I understand how to allow a user to upload an image, what I want is the user to have to select from a set of images that I provide. – Blezx Aug 11 '15 at 19:27

2 Answers2

2

Basic example. Models:

def get_upload(instance, filename):
    return "uploaded_files/user_%s_%s_%s" % (instance.user, datetime.datetime.today().strftime("%d-%m-%Y %H-%M-%S"), filename)

class UserModel():
    # your fields
    image = models.FileField(upload_to=get_upload, default='')

FileField

Forms:

class UploadForm(forms.ModelForm):
    """Auxiliary class to make file uploading more convenient."""
    def __init__(self, *args, **kwargs):
        super(UploadForm, self).__init__(*args, **kwargs)

    class Meta:
        model = UserModel
        fields = ('image')

View:

def upload(request):
    if request.method == "POST":
        profile = request.user.profile
        image_type = request.POST.get("image_type", None)
        if image_type == "blah":
            profile.image = request.FILES[image_type]
        else:
            return HttpResponse("Error")
        request.user.profile.save()
        return HttpResponse('OK')

request.FILES

JS with soem Jquery:

var SIZE_RESTRICT = 10*1024*1024;       //10 Mbytes

$(document).ready(function()
{
    $(".upload_file").find(".upload_button").click(send_file);
    $(".upload_file").find(".upload_file_form").find("input[type='file']").click(enable_upload);
});

function send_file()
{
    if ($(this).attr("enabled") != "true") return;
    // Prevent double-triple clicks with multiple upload.
    $(this).attr("enabled", "false");
    var form = $(this).parent().find(".upload_file_form").get(0);
    var formData = new FormData(form);
    var file = $(form).find("input[type='file']").get(0).files[0];
    // Not sure about this
    // Prevent attack with HUGE files, that will smash server memory
    // TODO: Restrict file types (Ex. MIME-image, pdf, doc)
    if (file.size > SIZE_RESTRICT)
    {
        alert("File is too big.");
        return;
    }
    formData.append("proof_type", $(this).attr("upload-type"));
    var xhr = new XMLHttpRequest();
    var that = this;
    // TODO: Define another events like error, abort
    xhr.upload.onprogress = function(e) {
        // TODO: Progressbar as e.loaded / e.total
        if (e.lengthComputable)
            console.log((e.loaded / e.total) * 100);
        else
            console.log("Cant count length");
      };

    xhr.onload = function(e){
          // TODO: Show success confirmation to user.
        if (this.response == "Success")
        {
            // pass
            alert(this.response);
        }
        else if (this.response == "Error")
        {
            // pass
            alert(this.response);
        }
        else
        {
            // pass
        }
      };

    xhr.open('POST', '/upload_proof');
    xhr.send(formData);
}

function enable_upload()
{
    $(this).parent().parent().find(".upload_button").attr("enabled", "true");
}

Actually another simple example could be founded in docs

m9_psy
  • 3,217
  • 5
  • 25
  • 38
1

If the set of images is small and fixed, the best option is to use the choice attribute in the field that defines the image within your model.

The image field could be the path to the image file on the file system.

class UserProfile(models.Model):
    GOOD = 'Good.jpg'
    UGLY = 'Ugly.jpg'
    BAD = 'Bad.jpg'
    AVATAR_CHOICES = (
        (GOOD, 'Good'),
        (UGLY, 'Ugly'),
        (BAD, 'Bad'),
    )
    avatar_img = models.CharField(max_length=255,
                                  choices=AVATAR_CHOICES,
                                  default=GOOD)

Another option is to use FilePathField as your model field

FilePathField(path="/path/to/avatar_images", match="*.jpg", recursive=False)

Another way is to fill the form field dynamically when the form is instantiated. Please see this SO QA for more on that.

However, as Django docs say

But if you find yourself hacking choices to be dynamic, you’re probably better off using a proper database table with a ForeignKey

To specify Radiobuttons to be used for the form field, please refer to the official docs on how to set the proper widget.

Community
  • 1
  • 1
Pynchia
  • 10,996
  • 5
  • 34
  • 43