2010-09-08 72 views
4

我想重写保存在的ModelForm当前用户添加为车辆的所有者。但我收到'NoneType'对象没有属性'user' 我忘了什么?如何访问请求的ModelForm添加request.user为外键

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 

我的模型:

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's schedule" %self.name) 

    class Meta: 
     unique_together = (("name", "owner",),) 

def __unicode__(self): 
    return u'%s: %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, },) 

我使用的是通用的看法:

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

你忘了'ModelForm'有没有属性'request',所以'self.request'在'save'方法' None'。 – 2010-09-08 08:46:22

+0

@Dominic:请参阅表单的'__init__'方法。用户正在基于'kwargs'设置'self.request'。 – 2010-09-08 08:50:51

+0

@Manoj - 啊,谢谢。 – 2010-09-08 08:53:31

回答

3

我想添加到马诺的和丹尼尔的反应多一点信息。基本上我需要自定义视图,以便在所述用户通过上节省:

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',) 
2

你没有表现你是如何实例化形式在你看来。你需要记住实际上传递的要求,当你这样做的:

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

+1。发布代码以显示如何实例化表单。 – 2010-09-08 08:50:18

+0

我使用的是通用的看法,上述补充这一点。因此,我应该按照您的示例使用自定义视图? – Dan1ell 2010-09-08 15:45:35

+0

是的,你要在这里需要自定义视图。 – 2010-09-09 06:18:42

3

下面是我怎么会写的观点,这些天更短的版本,只是对未来的眼睛。 无需任何__init__子类,并没有形式构造的重复:

@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})