0

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!

Bob
  • 283
  • 1
  • 4
  • 14

1 Answers1

1

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

serg
  • 109,619
  • 77
  • 317
  • 330
  • Thanks for responding! So I should acquire the id using that, and use it as a pk, right? Like so? userform = ImgDocForm(request.POST, request.FILES, pk=request.user.id) – Bob Mar 07 '16 at 07:00
  • @Bob Are you trying to create ImgDoc from the uploaded file? You can just assign it to your `ImgDoc.user` field. if you want to assing it to a form see http://stackoverflow.com/questions/18246326/in-django-how-do-i-set-user-field-in-form-to-the-currently-logged-in-user – serg Mar 07 '16 at 17:41
  • Thanks for responding @serg !! Yes, I'm trying to store the file into ImgDoc. The example you linked doesn't seem to work unfortunately, but perhaps I implemented it wrongly? At the moment I'm trying to use formsets to get the job done, is that recommended? Or is that the wrong way to go about it? Reason why I used that is because I had a similar project before, two related models, I couldn't save to the child model. Using formsets allowed me to do this. . In this case however, I'm not using ID captured from the URL. In a moment, I'll paste my current code below for you to check out. – Bob Mar 08 '16 at 02:49
  • Thanks for the help @serg! I didn't need to use formsets or anything complicated. A basic file save appeared to do the trick, with the model referencing the instance as "request.user.id". I'll post the solution above as an edit above in a moment (if anyone's curious). – Bob Mar 08 '16 at 13:17