Инициализация поля пользователя django ModelForm с текущим зарегистрированным пользователем
Я пытаюсь инициализировать некоторые поля моей NewArticleForm статическими данными. В частности, я хочу установить поле author с текущим зарегистрированным пользователем/автором, и оно не должно быть изменяемым. Эта страница доступна только для залогиненного пользователя, и информация также хранится в 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})
Как я могу установить автора с текущим зарегистрированным пользователем?
Бонусный вопрос: Почему поле pub_date, которое является DateTimeField, отображается как text? Я не могу его изменить.
В 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
Request.user уже включен через аргумент request в представлении. Поскольку требуется вход, вы знаете, что это не будет анонимный пользователь.
Таким образом, вы можете ссылаться на него в файле 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!')
Поскольку у вас уже есть эта информация, и вы не можете переопределить значение author, нет смысла включать ее в форму в качестве поля.
class NewArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'pub_date']
Дополнительно, поскольку страница требует входа и всегда будет ссылаться на вошедшего пользователя, вам не нужно включать userid в URL, поскольку вы всегда можете получить значение либо request.user
в представлении, либо {{request.user}}
в шаблоне. Раскрытие идентификатора пользователя представляет собой некоторый риск для безопасности, так как раскрывает информацию о пользователе базы данных.
Бонусный ответ:
Я полагаю, что DateTimeField использует текст в качестве ввода для поддержки наиболее широкого диапазона браузеров. input type = date
является относительно новым, и, к сожалению, виджеты браузеров по умолчанию не очень доступны, в то время как текст обычно доступен.