IntegrityError at * Ошибка ограничения NOT NULL: main_post.owner_id

Я хочу создать PostModel (так же, как instagram), и пока создается форма для подключения пользователя к модели с отношением «один к одному/внешний ключ», в любом случае у меня возникает проблема при попытке загрузить изображение и БД не обновляется.

Я пробовал это решение

...
# models.py
from django.contrib.auth.models import User
from django.conf import settings

class Post(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    description = models.CharField(max_length=255, blank=True)
    image = models.ImageField(upload_to='images')
    uploaded_at = models.DateTimeField(auto_now_add=True)


...
# forms.py
class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('description', 'image', )

    def save(self, commit=True):
        if commit:
            Post.save()
        return Post

...
# views.py
def account(request):
    post = PostForm(request.POST, request.FILES)
    if request.method == "POST":
        if post.is_valid():
            post.save(commit=False)
            post.owner = request.user
            post.save(commit=True)
            messages.success(request, f"you had successfully updated your profile image")
            return redirect("main:account")
        else:
            for msg in form.error_messages:
                messages.error(request, f"{msg}: {form.error_messages[msg]}")

            return render(request = request,
                          template_name = "main/account.html",
                          context = {'PostForm':post})

    post = PostForm()
    return render(request = request,
                  template_name = "main/account.html",
                  context = {'PostForm':post})

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

Willem Van Onsem 22.12.2020 17:06

просто поделился бро :)

yaron shamul 22.12.2020 17:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
662
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не должны переопределять метод def save(), сейчас это нормально, поэтому:

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('description', 'image', )

    # no save

что касается представления, вам нужно добавить владельца к объекту, но здесь вы добавляете его к форме, и это, таким образом, не имеет никакого эффекта (на объект):

from django.contrib.auth.decorators import login_required

@login_required
def account(request):
    post = PostForm(request.POST, request.FILES)
    if request.method == 'POST':
        if post.is_valid():
            post.instance.owner = request.user
            post.save()
            messages.success(request, f'you had successfully updated your profile image')
            return redirect('main:account')
    # …

Я бы еще посоветовал переименовать post в post_form, так как это форма, а не объект поста.


Примечание: Вы можете ограничить представления до представления для аутентифицированных пользователей с @login_required декоратор [Django-doc].

Я так ценю вашу помощь! Теперь у меня другая проблема, с объектами все в порядке, но я не могу отобразить изображение, <img src='{{post_form.image.path}}'> (я изменил способ, которым я назвал пост, как вы посоветовали)

yaron shamul 22.12.2020 17:23

@yaronshamul: у формы нет изображения. Как уже было сказано, существует разница между формой PostForm, которая проверяет данные, очищает их и может сохранять в базе данных, и объектом Post. Например, вы можете визуализировать его, учитывая, что изображение существует с {{ post_form.instance.image.url }}. Но вы здесь, в случае успешного POST, сделаете перенаправление, поэтому страница, на которую вы перенаправляете, должна правильно отображать изображение.

Willem Van Onsem 22.12.2020 17:29

во-первых, спасибо за информацию, есть ли у вас какие-либо ресурсы, чтобы углубиться в эту тему? (вместо документа я пойду туда сразу после исправления этой проблемы) и есть ли еще случаи, в которых экземпляры и формы могут сбивать с толку? поэтому я попробовал ваше решение выше, и оно плохо отображается.. html здесь

yaron shamul 22.12.2020 17:50

@yaronshamul: как передать это в шаблон?

Willem Van Onsem 22.12.2020 17:52
ссылка на функцию
yaron shamul 22.12.2020 17:54

кажется, что он не может прочитать экземпляр после сообщения, я напечатал {{post_form.instance}} и получил объект Post (None), но с БД все в порядке

yaron shamul 22.12.2020 18:18

@yaronshamul: но в случае, если вы отправили это в форму, и форма приняла это, вы делаете return redirect('main:account'). Это представление (к которому переходит account) должно получать связанные Post (их может быть несколько) и, таким образом, отображать его правильно. Таким образом, это не представление, которое отправляет изображение. Таким образом, в новом представлении вы можете получать сообщения с помощью posts = Post.objects.filter(owner=request.user), а затем в шаблоне отображать это, например, с помощью {% for post in posts %}{{ post.image.url }}{% endfor %}.

Willem Van Onsem 22.12.2020 18:21

Давайте продолжим обсуждение в чате.

yaron shamul 22.12.2020 18:30

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