【问题标题】:How to access request in ModelForm for adding request.user as foreign key如何在 ModelForm 中访问请求以添加 request.user 作为外键
【发布时间】:2024-01-04 18:27:01
【问题描述】:

我正在尝试覆盖模型表单中的保存以将当前用户添加为车辆的所有者。但我收到“NoneType”对象没有“用户”属性 我忘记了什么?

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

【问题讨论】:

  • 您忘记了ModelForm 没有属性request,因此您的save 方法中的self.requestNone
  • @Dominic:查看表单的__init__ 方法。用户正在根据kwargs 设置self.request

标签: django overriding save foreign-key-relationship modelform


【解决方案1】:

您没有在视图中显示您是如何实例化表单的。您需要记住在这样做时实际传递请求:

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

【讨论】:

  • +1。发布代码以显示您如何实例化表单。
  • 我使用的是通用视图,在上面添加了这个。因此,我应该按照您的示例使用自定义视图?
  • 是的,您需要在这里自定义视图。
【解决方案2】:

我想在 Manoj 和 Daniel 的回复中添加更多信息。基本上我需要一个自定义视图才能在保存时传递用户:

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】:

    这是我最近如何编写视图的简短版本,仅供将来参考。 无需任何__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})
    

    【讨论】:

      最近更新 更多