Django,将已排除的属性添加到提交的模型中

时间:2011-04-29 12:11:57

标签: django django-models django-forms modelform

我有一个模型表格,我排除了两个字段create_datecreated_by字段。现在,使用save()方法时出现“Not Null”错误,因为created_by为空。

我尝试在save()方法之前将用户ID添加到表单中,如下所示:form.cleaned_data['created_by'] = 1form.cleaned_data['created_by_id'] = 1。但这一切都不起作用。

有人可以向我解释如何在提交的模型中“添加”其他内容以便保存吗?

class Location(models.Model):
    name = models.CharField(max_length = 100)
    created_by = models.ForeignKey(User)
    create_date = models.DateTimeField(auto_now=True)

class LocationForm(forms.ModelForm):
    class Meta:
        model = Location
        exclude = ('created_by', 'create_date', )

4 个答案:

答案 0 :(得分:18)

由于您已排除表单中的字段created_bycreate_date,因此尝试通过form.cleaned_data分配字段没有任何意义。

以下是您可以做的事情:

如果您有视图,只需使用form.save(commit=False),然后设置created_by的值

def my_view(request):
    if request.method == "POST":
        form = LocationForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.created_by = request.user
            obj.save()
        ...
        ...

`

如果您使用的是管理员,则可以覆盖save_model()方法以获得所需的结果。

class LocationAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.created_by = request.user
        obj.save()

答案 1 :(得分:4)

将用户作为参数传递给表单构造函数,然后使用它来设置模型实例的created_by字段:

def add_location(request):
    ...
    form = LocationForm(user=request.user)
    ...

class LocationForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(forms.ModelForm, self).__init__(*args, **kwargs)
        self.instance.created_by = user

答案 2 :(得分:1)

正确的解决方案是将具有预填充字段的对象实例传递给模型表单的构造函数。这样,字段将在验证时填充。如果需要字段,则在form.save()之后分配值可能会导致验证错误。

LocationForm(request.POST or None, instance=Location(
    created_by=request.user,
    create_date=datetime.now(),
))

请注意,实例是未保存的对象,因此在表单保存之前不会分配id。

答案 3 :(得分:0)

执行此操作的一种方法是使用form.save(commit = False)(doc

这将返回模型类的对象实例,而不将其提交给数据库。

因此,您的处理可能如下所示:

form = some_form(request.POST)
location = form.save(commit=False)
user = User(pk=1)
location.created_by = user
location.create_date = datetime.now()
location.save()