Bob
Bob

Reputation: 329

Submit to form without relying on URL

Okay so it appears I'm in way over my head on this small task. I'd like to ask how exactly does one submit to a form, without relying on the URL values?

In my example, the user has to log in before they can see their gallery pictures. Determining this is via "context", which has the active user (as logged in) assigned to it. Props to @chem1st & @Daniel-Roseman for the assistance earlier in helping me figure that out yesterday. Now it can display their own user gallery in the homepage after they log in.

I prefer not uploading with "blahblah.com/bobby/upload", because it doesn't seem very secure. I'd like to let logged in users upload via "blahblah.com/upload/". Which means the form in the view.py would have to get the context of the user who's logged in, somehow, and save the data to the database under that account.

I've been toying around, and searching for answers, but can't find anything. Can someone help point me in the right direction?

Here's my models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    activation_key = models.CharField(max_length=40, blank=True)
    key_expires = models.DateTimeField(default=datetime.date.today())

    def __str__(self):
        return self.user.username

    class Meta:
        verbose_name_plural='User profiles'


class ImageDoc(models.Model):
    user = models.ForeignKey(UserProfile)
    imgfile = models.ImageField(upload_to='images/')

forms.py:

class RegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'E-mail address'}))
    first_name = forms.CharField(required=True)
    last_name = forms.CharField(required=True)


    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'username', 'password1', 'password2')


    class ImgDocForm(forms.Form):
        user_file = forms.ImageField()


    def clean_user_file(self, *args, **kwargs):
        cleaned_data = super(ImgDocForm,self).clean()
        user_file = cleaned_data.get("user_file")

        if user_file:
            if user_file.size > 5 * 1024 * 1024:
                raise forms.ValidationError("Filesize is too big.")

            if not os.path.splitext(user_file.name)[1].strip().lower() in ['.jpg','.png','.gif','.jpeg']:
                raise forms.ValidationError("File does not look like as picture.")

        return user_file


    class UserForm(forms.Form):
        class Meta:
            model = User
            fields = ['first_name', 'last_name', 'password', 'email', 'username']

My views.py file (EDIT: Changed the Index to display the user details, the gallery, and a quick upload function):

def sign_in(request):
    context = RequestContext(request)

    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)

        if user:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/', context)
            else:
                return HttpResponse("Verify your account!")
        else:
            return HttpResponse("Invalid login details supplied.")


def populateContext(request, context):
    context['authenticated'] = request.user.is_authenticated()
    if context['authenticated'] == True:
        context['username'] = request.user.username


def index(request):
    user_details = UserProfile.objects.get(user=request.user)
    gallery = ImageDoc.objects.filter(user_id=request.user.id)

    if request.method == 'POST':
        form = ImgDocForm(request.POST, request.FILES)
        if form.is_valid():
            origin_form = form.cleaned_data["user_file"]
            origin_name = origin_form.name

            original_name = ImageDoc(user_id=request.user.id, imgfile=origin_name)
            original_name.save()

            return HttpResponse('Saved!')
    else:
        form = ImgDocForm()

    documents = ImageDoc.objects.all()

    return render(request, 'test.html', {'documents': documents, 'form': form, 'user_details': user_details, 'gallery': gallery})




def upload(request):
    data = {}
    thumb_size = (100,100)
    micro_thumb_size = (50,50)

    if request.method == 'POST':
        userform = ImgDocForm(request.POST, request.FILES)

        if userform.is_valid():
            origin_form = userform.cleaned_data["user_file"]
            origin_name = origin_form.name
            original_file = os.path.join(settings.MEDIA_ROOT, origin_name)

            .
            .
            .

            original_name = ImageDoc(imgfile=origin_name)
            original_name.save()

            .
            .
            .

            userform = ImgDocForm()
        else:
            return HttpResponse('Nooo!')

    else:
        userform = ImgDocForm()

    data.update(image_gallery = ImageDoc.objects.only('imgfile'))
    data.update(userform=userform)
    data.update(csrf(request))
    return render(request, 'upload.html', data)

EDIT: I'm sure folks can clean up the index file significantly. Also, not very elegant at the bottom there, but it works.

And the upload.html document:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body>

<div>

    <form method="post" action="" enctype="multipart/form-data">
        {% csrf_token %}
        {{ userform.as_p }}
        <input type="submit">
    </form>

    <br><br>

    <h2>{{ origin_name }} (original)</h2>

    {% if origin_name %}
        <img src="{{ MEDIA_URL }}{{ origin_name }}">
    {% endif %}

    <br><br>
    {% if image_gallery %}
        {% for image in image_gallery %}
            <img src="/{{ image.thumbfile }}">
        {% endfor %}
    {% endif %}    
</div>
</body>
</html>

Thank you!

Upvotes: 0

Views: 79

Answers (1)

serg
serg

Reputation: 111255

You can get currently logged in user inside the view as request.user.

Upvotes: 1

Related Questions