I'm having a problem with logged users and a Django ModelForm
. I have a class named _Animal_
that has a ForeignKey
to User
and some data related to the animal like age, race, and so on.
A user can add Animals to the db and I have to track the author of each animal, so I need to add the request.user that is logged when the user creates an animal instance.
models.py
class Animal(models.Model):
name = models.CharField(max_length=300)
age = models.PositiveSmallIntegerField()
race = models.ForeignKey(Race)
...
publisher = models.ForeignKey(User)
def __unicode__(self):
return self.name
class AnimalForm(ModelForm):
class Meta:
model = Animal
The main goal is hide the publisher field in the form, and submit the logged user when hitting save button.
I can catch the current user in the view using initial
, but what I also want is not display the field.
views.py
@login_required
def new_animal(request):
if request.method == "POST":
form = AnimalForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
variables = RequestContext(request, {'form': form})
return render_to_response('web/animal_form.html', variables)
else:
form = AnimalForm(initial={'publisher': request.user})
variables = RequestContext(request, {'form': form})
return render_to_response('web/animal_form.html', variables)
You just need to exclude it from the form, then set it in the view.
class AnimalForm(ModelForm):
class Meta:
model = Animal
exclude = ('publisher',)
... and in the view:
form = AnimalForm(request.POST)
if form.is_valid():
animal = form.save(commit=False)
animal.publisher = request.user
animal.save()
(Note also that the first else
clause - the lines immediately following the redirect - is unnecessary. If you leave it out, execution will fall through to the two lines at the end of the view, which are identical.)
Another way (slightly shorter):
You need to exclude the field as well:
class AnimalForm(ModelForm):
class Meta:
model = Animal
exclude = ('publisher',)
then in the view:
animal = Animal(publisher=request.user)
form = AnimalForm(request.POST, instance=animal)
if form.is_valid():
animal.save()
I would add it directly to the form:
class AnimalForm(ModelForm):
class Meta:
model = Animal
exclude = ('publisher',)
def save(self, commit=True):
self.instance.publisher = self.request.user
return super().save(commit=commit)
This is in my opinion the cleanest version and you may use the form in different views.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With