Как добавить поле ForeignKey для сохранения в ModelForm Django?

Создавая свой сайт, я столкнулся со следующей проблемой: пользователь может добавить статью, поэтому в модели статьи есть поле ForeignKey — автор.

Форму для ее добавления я создал, унаследовав от ModelForm, так как считаю, что так логичнее (так как она напрямую взаимодействует с БД). Проблема в том, что я не могу добавить это поле в Форму, так как оно не может быть заполнено; его нужно взять из самого запроса.

author = request.user.pk

Итак, как я могу сделать так, чтобы форма также сохраняла идентификатор автора? Без него возникает ошибка: NOT NULL CONSTRAINT FAILED, что логично, поскольку форма не сохраняет pk и поэтому имеет значение null; но FOREIGN KEY не может быть нулевым.

Единственный способ — наследовать его от формы класса? Мне не очень хочется этого делать... Я думал о "переопределении" метода save(), чтобы у него был еще один аргумент - идентификатор автора:

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...

Поделитесь мнением...

willeM_ Van Onsem 24.06.2024 21:51

@willeM_VanOnsem отредактировал это

dasEgo 24.06.2024 22:09
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
2
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я полагаю, вы хотите использовать 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')

Да, спасибо вам огромное! Это то, что я искал!

dasEgo 25.06.2024 08:51

Другие вопросы по теме