I'm trying to initialize some fields of my NewArticleForm with static data. In particular, I want to set the author field with the current logged user/author, and shouldn't be modifyable. This page is reachable only from logged user, and the information is also stored in the url:
path('<int:user_id>/create', views.add_article, name='insert'),
forms.py:
class NewArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['author','title', 'content', 'pub_date']
pub_date = forms.DateTimeField(initial=timezone.now())
def save(self, commit=True):
article = super(NewArticleForm, self).save(commit=False)
if commit:
article.save()
return article
models.py:
from django.db import models
from django.contrib.auth.models import User
class Article(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
pub_date = models.DateTimeField()
title = models.CharField(max_length=50)
content = models.TextField()
def __str__(self):
return self.title
def get_year(self):
return self.pub_date.year
def get_month(self):
return self.pub_date.month
views.py:
@login_required
def add_article(request, user_id):
if request.method == 'POST':
form = NewArticleForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Articolo inserito con successo!')
return redirect('/blog_app/')
else:
messages.warning(request, 'Qualche campo non è corretto, operazione fallita.')
form = NewArticleForm()
return render(request, template_name='blog_app/insert.html', context={'insert_form':form})
How can I set author with the current logged user?
Bonus question: Why pub_date field, which is a DateTimeField, is displayed as text type? I can't change it.
CodePudding user response:
In forms.py
:
class NewArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['author','title', 'content', 'pub_date']
pub_date = forms.DateTimeField(initial=timezone.now())
def save(self, commit=True):
article = super(NewArticleForm, self).save(commit=False)
article.author = self.request.user # This is logged in user info
if commit:
article.save()
return article
CodePudding user response:
Request.user is already included via the request argument of the view. Because login is required you know it won't be an anonymous user.
You can thus refer to it in your view.py
@login_required
def add_article(request, user_id):
if request.method == 'POST':
form = NewArticleForm(request.POST)
if form.is_valid():
#We can add things to the form.instance before saving
#request has been passed as an argument to the view so we can get the user also
form.instance.author = request.user
#save the result and create a new db record
form.save()
messages.success(request, 'Articolo inserito con successo!')
Because you have this info already, and you can't override the author value, it doesn't make sense to include it as field in the form.
class NewArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'pub_date']
Additionally, because the page requires login, and it's always going to refer to the logged in user, you don't need to include the userid in the URL as you can always get the value either by request.user
in the view or {{request.user}}
in the template. Revealing a user_id is a bit of a security risk as it reveals db userinfo.
Bonus answer:
I'd imagine DateTimeField uses text as input to support the widest range of browsers. input type = date
is relatively new, and, unfortunately, the default browser widgets are not terribly accessible, whereas text usually is.