Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django – How Do I Set A Default Value In A Form To Be The Current User?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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 🙂

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading