Как добавить поле ForeignKey для сохранения в ModelForm Django?
При создании своего сайта я столкнулся со следующей проблемой: пользователь может добавить статью, и поэтому модель статьи имеет поле ForeignKey - author.
Я создал форму для его добавления, унаследовав ее от ModelForm, так как мне кажется, что так будет логичнее (ведь она взаимодействует напрямую с db). Проблема в том, что я не могу добавить это поле в форму, так как его нельзя заполнить, оно должно быть взято из самого запроса.
author = request.user.pk
Как сделать так, чтобы форма сохраняла и id автора? Без этого возникает ошибка: NOT NULL CONSTRAINT FAILED
, что логично, так как форма не сохраняет пк и поэтому он равен null; но FOREIGN KEY
не может быть null.
Единственный способ - наследовать его от класса Form? Я не очень хочу этого делать... Я думал о "переопределении" метода save()
так, чтобы у него был еще один аргумент - id автора:
form.save(author=request.user.pk)
Таким образом это будет работать. Но я передумал, потому что если что-то пойдет не так, это испортит всю базу данных... Метод save()
слишком глобальный. Более того, вполне может существовать другой способ решения моей проблемы, более эффективный и понятный.
Вот код для моей формы:
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['title', 'content']
widgets = {'title' : TextInput(attrs={'class' : 'create_article_title',
'placeholder' : 'Enter the heading...' }),
'content' : Textarea(attrs={'class' : 'create_article_content',
'placeholder' : 'Your article...' })}
и моя модель:
class Article(Model):
title = CharField(max_length=30)
content = CharField(max_length=5000)
author = ForeignKey(User, on_delete=CASCADE)
rating = IntegerField(default=0)
created = DateField(auto_now_add=True)
last_updated = DateField(auto_now_add=True)
articles = ArticleManager()
objects = Manager()
и мое мнение:
class AddArticle(View):
template_name = 'myapp/addarticle.html'
def get(self, request):
context = {'add_article_form' : ArticleForm()}
return render(request, self.template_name, context=context)
def post(self, request):
form = ArticleForm()
form.save()
return redirect('index')
Похоже, я совершенно не понимаю основ создания ModelForm...
Я полагаю, что вы хотите использовать FormView и сделать что-то вроде этого:
class AddArticle(LoginRequiredMixin, FormView):
form_class = ArticleForm
template_name = 'myapp/addarticle.html'
success_url = 'index'
def get(self, request, *args, **kwargs):
context = {'add_article_form' : ArticleForm()}
return render(request, self.template_name, context=context)
def form_valid(self, form):
form = form.save(commit=False)
form.user = self.request.user
form.save()
return redirect(self.success_url)
Это возможный дубликат Как установить поле пользователя в форме на текущего вошедшего пользователя?
Есть и другие способы. Например, добавить в форму поле hidden
и установить его значение как request.user.id
.
Хотя, должен сказать, что ваша первоначальная мысль, связанная с методом save()
, правильная. Однако не переопределять его, а использовать необязательное ключевое слово, предоставляемое самим методом.
Также не забудьте установить данные формы и validate
ее, что является одной из главных особенностей:
class AddArticle(View):
...
def post(self, request):
form = ArticleForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
return redirect('index')