Home > front end >  Django - How Do I Set A Default Value In A Form To Be The Current User?
Django - How Do I Set A Default Value In A Form To Be The Current User?

Time:01-03

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.

  • Related