简体   繁体   中英

How to add the logged in user's username with django

I am building a basic blog site with Django which currently asks for the writer to define his/her name when making blog. However, I would want the site to automatically put in the logged in user's username in the author field of my models.

Here's my views.py ( AddPostView should be the relevant class):

class HomeView(ListView):
    model = Post
    template_name = 'community.html'
    ordering = ['-id']

class ArticleDetailView(DetailView):
    model = Post
    template_name = 'articles_details.html'

class AddPostView(CreateView):
    model = Post
    form_class = PostForm
    template_name = 'add_post.html'
    #fields = '__all__'

And here's my forms.py :

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title','author', 'body', 'image']

        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'author': forms.TextInput(attrs={'class': 'form-control'}),
            'body': forms.Textarea(attrs={'class': 'form-control'}),
        }

And models.py :

class Post(models.Model):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255, null=True)
    #author = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    image = models.ImageField(null=True, blank=True, upload_to='images/qpics')

    def __str__(self):
        return self.title + ' - ' + self.author

    def get_absolute_url(self):
        return reverse('community')

I do get that I have to remove the author from forms.py and change it accordingly into models.py and write a code in views.py but i can't find a working solution to my problem. Most of the answers online are for class based views and do not work for me.

Little help will be appreciated. THANKS!

not sure why you commented out the author field as FK but you can do it this way:

class AddPostView(CreateView):
    model = Post
    form_class = PostForm
    template_name = 'add_post.html'
 
    def get_form_kwargs(self, *args, **kwargs):
        kwargs = super().get_form_kwargs(*args, **kwargs)
        kwargs['name'] = self.request.user.username
        return kwargs

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title','author', 'body', 'image']
    
    def __init__(self, name, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.field['author'].widget.attrs.update({'class': 'form-control',
                                                  'value': f'{name}'})      
<form method="POST">
    {{ form.author }}
</form>

another short way is to render form input manually inside template

<form method="POST">
    <input type="text" id="id_author" name="author" maxlength="255" value="{{user.username}}" class="form-control">
</form>

I think you're on the right track. You'll want to have your Post.author be a ForeignKey to the User model. Set this value in the view's form_valid() method to ensure that it doesn't get tampered with by a bad actor during form presentation.

models.py

class Post(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    image = models.ImageField(null=True, blank=True, upload_to='images/qpics')

    def __str__(self):
        return self.title + ' - ' + self.author

    def get_absolute_url(self):
        return reverse('community')

forms.py

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'author', 'body', 'image']

        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            # Hide the author field in the form, we'll overwrite it later
            'author': forms.HiddenInput(),
            'body': forms.Textarea(attrs={'class': 'form-control'}),
        }

views.py

class AddPostView(CreateView):
    model = Post
    form_class = PostForm
    template_name = 'add_post.html'

    def form_valid(self, form):
        # Set the form's author to the submitter if the form is valid
        form.instance.author = self.request.user
        super().form_valid(form)

For bonus points, you can also set the author within Django Admin using a similar approach:

admin.py

@admin.register(Post)
class PostAdmin(admin.ModelAdmin)
    form = PostForm

    def save_model(self, request, obj, form, change):
        obj.author = request.user
        super().save_model(request, obj, form, change)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM