Django form.is_valid () возвращает False - PullRequest
0 голосов
/ 23 января 2020

Я создаю блог в Django и застрял при добавлении записи post_update_view, где form.is_valid () возвращает False , и я не могу обновить сообщение.

Я также проверил это , но я не смог перейти в нужное место.

Кроме того, это странно, так как при создании поста form.is_valid() работает нормально (я назначаю " form = PostModelForm(request.POST or None) "там).

Буду признателен за любые предложения.

Ниже:

Views.py

def post_update_view(request, slug):
    obj = get_object_or_404(Post, slug=slug)
    form = PostModelForm(request.POST or None, instance=obj)
    print(form.is_valid())
    if form.is_valid():
        form.save()
    template_name = 'blog/post_update.html'
    context = {'form': form, 'title': f'Update {obj.title}'}
    return render(request, template_name, context)

models.py:

from django.conf import settings
from django.db import models

User = settings.AUTH_USER_MODEL

class Post(models.Model):
    CATEGORY_CHOICES = (
        (None, '--------'),
        ('CB', 'City Break'),
        ('1W', 'Week holidays'),
        ('2W', 'Two weeks holidays'),
        ('MO', 'Month holidays'),
        ('SB', 'Sabbatical'),
    )

    CONTINENT_CHOICES = (
        (None, '--------'),
        ('AS', 'Asia'),
        ('AU', 'Australia and Oceania'),
        ('AF', 'Africa'),
        ('EU', 'Europe'),
        ('NA', 'North America'),
        ('SA', 'South America'),
    )

    user = models.ForeignKey(
        User,
        default=1,
        null=True,
        on_delete=models.SET_NULL
    )
    title = models.CharField(max_length=150)
    date = models.DateField()
    category = models.CharField(
        max_length=100,
        choices=CATEGORY_CHOICES,
        blank=True
    )
    continent = models.CharField(
        max_length=100,
        choices=CONTINENT_CHOICES,
        blank=True
    )
    body = models.TextField()
    slug = models.SlugField()

    def __str__(self):
        return self.slug

forms.py:

from django import forms
from blog.models import Post


class PostModelForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'date', 'category', 'continent', 'slug', 'body']

    def clean_slug(self):
        instance = self.instance
        slug = self.cleaned_data.get('slug')
        qs = Post.objects.filter(slug__iexact=slug)
        qs_title_id = 0
        if instance is not None:
            qs = qs.exclude(pk=instance.pk)
        if qs.exists():
            raise forms.ValidationError(f"Slug has already been used in "
                                        f"'{qs[qs_title_id]}'.\n Please "
                                        f"change.")
        return slug

шаблоны

{% extends "site_general/header.html" %}

{% block content %}
    {% if title %}
        <h1>{{ title }}</h1>
    {% endif %}

    <form method="POST" action="."> {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Update</button>
    </form>

{% endblock %}

urls

from django.urls import path
from .views import (
    post_delete_view,
    post_detail_view,
    post_list_view,
    post_update_view,
)

urlpatterns = [
    path('', post_list_view),
    path('<str:slug>/', post_detail_view),
    path('<str:slug>/edit', post_update_view),
    path('<str:slug>/delete', post_delete_view),
]

1 Ответ

0 голосов
/ 23 января 2020

Слишком долго для комментария, и я не уверен, решит ли это проблему, но bruno desthuillers ссылается на то, «как должен выглядеть взгляд». Важно отметить, что существует один путь кода для несвязанной формы (URL-адрес доступен через HTTP GET), а другой - для данных, передаваемых из браузера через HTTP POST.

Я всегда ненавидел способ, которым каноническая форма запутывает обработку подтвержденных данных формы с образцом с обеих сторон, и предлагал бы отменить тест достоверности и использовать немного Python волхвов c для объединения создайте экземпляр для случаев GET и POST:

def post_update_view(request, slug):
    obj = get_object_or_404(Post, slug=slug)
    args = [request.POST] if request.method == "POST" else []
    form = PostModelForm(*args, instance=obj)
    if request.method != "POST" or not form.is_valid(): 
        # GET or not valid 
        context = {'form': form, 'title': f'Update {obj.title}'}
        return render(request, 'blog/post_update.html', context)

    # the form validated, do the work and redirect
    form.save()
    return redirect("wherever you want, but redirect")

Если это не ответ, замените шаблон на простейший из возможных {{ form.as_p }} и кнопку отправки и посмотрите, исправляет ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...