How to access a request in ModelForm to add request.user as a foreign key

I am trying to override persistence in modelform to add the current user as the owner of the vehicle. But I get a "NoneType" object that does not have a user attribute, What do I forget?

forms.py:

class VehicleForm(ModelForm): class Meta: model = Vehicle exclude = ('slug', 'owner', ) def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) super(VehicleForm, self).__init__(*args, **kwargs) def save(self, *args, **kwargs): kwargs['commit']=False obj = super(VehicleForm, self).save(*args, **kwargs) obj.owner = self.request.user obj.save() return obj 

my model:

 class VehicleBase(models.Model): owner = models.ForeignKey(User) vehicle_type = models.SmallIntegerField(_('kind'), choices=vehicle_types, default=1,) make = models.CharField(_('make'), max_length=31, help_text=_('Maximum is 31 characters.'), ) model = models.CharField(_('model'), max_length=31, help_text=_('Maximum is 31 characters.'), ) class Meta: abstract = True class Vehicle(VehicleBase): name = models.CharField(_('fun name'), max_length=31, help_text=_('Maximum is 31 characters.'), ) slug = models.SlugField(_('slug'), ) def save(self, *args, **kwargs): is_new = self.pk is None if is_new: self.slug = slugify("%s %s %s" %(self.make, self.model, self.name, )) super(Vehicle, self).save(*args, **kwargs) # Call the "real" save() method. if is_new: Calendar.objects.get_or_create_calendar_for_object(self, name = "%s schedule" %self.name) class Meta: unique_together = (("name", "owner", ), ) def __unicode__(self): return u'%s: %s\ %s %s' %(self.name, self.owner, self.make, self.model, ) def __str__(self): return self.__unicode__() def get_absolute_url(self): return reverse('vehicle_view', kwargs={'object_id':self.id, 'slug':self.slug, }, ) 

I use the general view:

 url(r'^create/$', 'create_update.create_object', dict(template_name='vehicles/vehicle_create.html', form_class=VehicleForm, post_save_redirect="/vehicles/"), name='vehicle_create'), 
+4
source share
3 answers

I wanted to add a little more information to the answers of Manoah and Daniel. Basically, I needed a custom view to pass it to the user when saving:

urls.py:

 url(r'^create/$', 'create_vehicle', name='vehicle_create'), 

views.py:

 @login_required def create_vehicle(request): if request.method == 'POST': form = VehicleForm(request.POST) if form.is_valid(): vehicle = form.save(commit=False) vehicle.owner = request.user vehicle.save() return HttpResponseRedirect('/vehicles/') else: form = VehicleForm() return render_to_response('vehicles/vehicle_create.html', {'form': form}, context_instance=RequestContext(request)) 

forms.py:

 class VehicleForm(ModelForm): class Meta: model = Vehicle exclude = ('slug', 'owner', ) 
+3
source

Here is a shorter version of how I will write an opinion these days, only for future eyes. There is no need for any subclass of __init__ and repetition of the form constructor:

 @login_required def create_vehicle(request): form = forms.VehicleForm(data=request.POST or None) if form.is_valid(): form.instance.owner = request.user form.save() return redirect('vehicles') return render(request, 'vehicles/vehicle_create.html', {'form': form}) 
+3
source

You do not show how you create the form in your view. You must remember to really pass the request when you do this:

 def myview(request): form = VehicleForm(instance=whatever, request=request) 
+2
source

All Articles