Django: How to set a hidden field on a generic create view?
Asked Answered
W

3

6

I'm running Django 1.6.x

To extend my user I've added another model storing the data:

class UserProfile (models.Model):
    user = models.ForeignKey(User)
    height = models.IntegerField(blank=True, null=True)

Now I wand to add a view, which is allowing the user to add its own infos there. Started with django.views.generic.edit.CreateView, but want also to provide at least the edit/update one to.

So I've added the import and created a view:

from django.views.generic.edit import CreateView, UpdateView
# .... 
class UserProfileCreateView(CreateView):
    model = UserProfile
    fields = ['height']

Also I've added the entry inside urls.py:

    url(r'^userprofile/new/$', login_required(UserProfileCreateView.as_view()), name="add_userprofile")

But now I'm stuck on the point how to assign the user ID in the correct way. I want to have this field set in background. Any hints?

Wizard answered 8/2, 2014 at 21:33 Comment(0)
R
25

You can do it that way:

  • get user from request object.
  • overwrite form_valid method on your UserProfileCreateView class,
  • attach user to form instance and save it.
class UserProfileCreateView(CreateView):
    model = UserProfile
    fields = ['height']

    def form_valid(self, form):
        user = self.request.user
        form.instance.user = user
        return super(UserProfileCreateView, self).form_valid(form)

This code is for Python 2.7.x

Remit answered 8/2, 2014 at 21:50 Comment(1)
Doesn't work for me. Because those fields are not filled, it never validates as true and so the code never runs :(Intrusion
B
2
class UserProfileCreateView(CreateView):
    def form_valid(self, form):
         self.object = form.save(commit=False)
         self.object.user = self.request.user
         self.object.save()
         return super(ModelFormMixin, self).form_valid(form)
Brochu answered 8/2, 2014 at 21:51 Comment(3)
Wouldn't this save the object even if it is not valid?Witted
this method call after validation in ProcessFormView,Brochu
Ah right. I'm not too used with the class based views. Thanks for clarifying.Witted
R
0

To avoid gottcha's like must be a “User” instance error you would want to try this.

 def form_valid(self, form):
        owner = self.request.user
        print("Bot owner1", owner)
        tenant = get_object_or_404(Tenant, user=owner)
        print("Bot owner2 ", tenant)
        form.instance.tenant = tenant

    return super().form_valid(form)

Turned out that

print("Bot owner1", owner)

and

print("Bot owner2 ", tenant)

have different results.

Any other approach besides the form_valid method could pose a security risk. i.e I could edit the initial value by inspecting element on your browser and put my new value. If your code does not validate my entry Bang!!!Bang!! you're hacked.

Revalue answered 24/12, 2018 at 1:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.