Инициализация поля пользователя 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 является относительно новым, и, к сожалению, виджеты браузеров по умолчанию не очень доступны, в то время как текст обычно доступен.

Вернуться на верх