quick beginner Django question because I haven't been able to find an answer that directly solves what i'm after, or doesn't add in a bunch of overcomplicated functionality I don't need with its answer.
I have a basic Blog setup, with a model for users and their associated posts, and a form for creating new posts. However all I want is for the "Author" field on the form to be automatically populated with the currently logged in user, rather than being a drop down list of all the registered users. My Model:
class Post(models.Model):
title = models.CharField(max_length=255)
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
post_date = models.DateField(auto_now_add=True)
category = models.CharField(max_length=255)
site = models.CharField(max_length=255)
def __str__(self):
return self.title ' | ' str(self.author)
def get_absolute_url(self):
return reverse('home')
My Form:
class PostForm(forms.ModelForm):
class Meta:
model=Post
fields = ('title', 'author', 'category', 'site', 'body')
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'author': forms.Select(attrs={'class': 'form-control' ,'readonly': 'readonly'}),
'category': forms.Select(choices=choice_list,attrs={'class': 'form-control'}),
'site': forms.Select(choices=site_choice_list,attrs={'class': 'form-control'}),
'body': forms.Textarea(attrs={'class': 'form-control'})
}
My View:
class AddPostView(CreateView):
model = Post
form_class = PostForm
template_name = 'add_post.html'
To reiterate, I simply want the 'author' field in the post to be read-only and populated with the current logged in user. Rather than the user being able to select from a list of users.
Thank you in advance, Let me know if I can provide anything else to help you help me :)
CodePudding user response:
You should disable the field, not just add a readonly
attribute to the widget, since a "hacker" can forge a malicious HTTP request that sets the author to another user:
class PostForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['author'].disabled = True
class Meta:
model = Post
fields = ('title', 'author', 'category', 'site', 'body')
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'author': forms.Select(attrs={'class': 'form-control'}),
'category': forms.Select(choices=choice_list,attrs={'class': 'form-control'}),
'site': forms.Select(choices=site_choice_list,attrs={'class': 'form-control'}),
'body': forms.Textarea(attrs={'class': 'form-control'})
}
We can then use this form in a view with:
from django.contrib.auth.mixins import LoginRequiredMixin
class AddPostView(LoginRequiredMixin, CreateView):
model = Post
form_class = PostForm
template_name = 'add_post.html'
def get_initial(self):
return {'author': request.user}
The LoginRequiredMixin
mixin [Django-doc] guarantees that only users that have logged in can see (and interact with) the view.