Reputation: 285
I run into this pattern all the time and I'm wondering if there's a better way to handle it. Lots of my models contemplate the idea of 'creator' - in other words, I want to make sure the user who created the object is saved as the creator. As such, my models almost always include
creator = models.ForeignKey(User)
There doesn't seem to be a way of defaulting this user to the user who created it (request.user). As such I find myself building model forms and adding creator as a HiddenInput()
class MyModelForm(ModelForm):
class Meta:
model = MyModelForm
fields = ['name', 'creator']
widgets = {
'creator': HiddenInput()
}
and then binding the form in the view with initial
form = MyModelForm(initial={'creator': request.user})
and checking on POST to make sure no one dickered with the form (full view):
def create(request):
form = MyModelForm(initial={'creator': request.user})
if request.method == 'POST':
if int(request.POST['creator']) != int(request.user.id):
return render(request,'500.html', {'message':'form tampering detected'})
form = FeedGroupForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('index'))
return render(request, 'mymodelformpage.html',{'form':form})
I'm fine with this but it seems like an anti-pattern. It strikes me that there ought to be a way to default the creator in the model.
creator = models.ForeignKey(User, default=request.user)
Or do it in a post_save perhaps?
Upvotes: 1
Views: 810
Reputation: 599956
No, this is not the right way. The correct way is to exclude the creator field from the form, then set it on save:
if form.is_valid:
obj = form.save(commit=False)
obj.creator = request.user
obj.save()
... redirect ...
Upvotes: 3