Django UpdateView AttributeError 'UserPostUpdateView' 对象没有属性 'publish'

Django UpdateView AttributeError 'UserPostUpdateView' object has no attribute 'publish'

编辑后尝试保存表单时出现错误。如果我重写 get_context_date(当前已注释掉),加载表单时会出现错误。

我已经查看了有关此问题的文档和以前的问题。 运行 的那些人已经覆盖了 post() 而我没有。所以我不知道为什么会这样,也不知道如何解决。非常感谢任何帮助。

回溯

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/mixins.py", line 71, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/edit.py", line 194, in post
    return super().post(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/edit.py", line 142, in post
    return self.form_valid(form)
  File "/code/mysite/create/views.py", line 22, in form_valid
    return super().form_valid(form)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/edit.py", line 126, in form_valid
    return super().form_valid(form)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/edit.py", line 57, in form_valid
    return HttpResponseRedirect(self.get_success_url())
  File "/code/mysite/create/views.py", line 25, in get_success_url
    return reverse_lazy("create:user_post_detail", kwargs={"year": self.publish.year, "month": self.publish.month, "day": self.publish.day, "slug": self.slug})

Exception Type: AttributeError at /create/my_collideas/2021/7/28/title-2-by-user2/edit/
Exception Value: 'UserPostUpdateView' object has no attribute 'publish'

#models.py

from django.core.validators import MinValueValidator
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.text import slugify
from ckeditor.fields import RichTextField

import sys
sys.path.append("..") # Adds higher directory to python modules path.
from userauth.models import CustomUser


class UserPost(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    publish = models.DateField(default=timezone.now, validators=[MinValueValidator(timezone.now().date(), message="The date cannot be in the past!")])
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, editable=False)
    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Published'),
    )
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default="draft")
    active = models.BooleanField(default=True, help_text="Allows moderator to unpublish posts if set to false") # Allows moderators to hide offensive posts
    inactive_message = models.TextField(max_length=500, blank=True, help_text="Enter the reason for setting this post to inactive")
    title = models.CharField(max_length=300, unique_for_date="publish", help_text="You must enter a title")
    slug = models.SlugField(max_length=350, unique_for_date="publish")
    content = RichTextField(config_name='awesome_ckeditor', help_text="You must enter some content")

    def save(self, *args, **kwargs):
        if not self.id:
            # Newly created object, so set slug
            self.slug = slugify(self.title)
        return super(UserPost, self).save(*args, **kwargs)
    
    def get_absolute_url(self):
        return reverse("create:detail", kwargs={"year": self.publish.year, "month": self.publish.month, "day": self.publish.day, "slug": self.slug})

    def __str__(self):
        return self.title
    
    class Meta:
        verbose_name = "User Post"
        verbose_name_plural = "User Posts"
        ordering = ("-publish",)

#views.py

from django.forms import DateInput
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.utils import timezone
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView

from .models import UserPost


class OwnerMixin(object):
    """Returns only user's objects to prevent others from accessing."""
    def get_queryset(self):
        qs = super().get_queryset()
        return qs.filter(user=self.request.user)


class OwnerEditMixin(object):
    """Sets user pk"""
    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)
    
    def get_success_url(self):
        return reverse_lazy("create:user_post_detail", kwargs={"year": self.publish.year, "month": self.publish.month, "day": self.publish.day, "slug": self.slug})


class UserPostCreateView(LoginRequiredMixin, OwnerEditMixin ,CreateView):
    model = UserPost
    fields = ["publish", "status", "title", "content"]
    template_name = "create/post.html"

    def get_form(self):
        form = super().get_form()
        form.fields['publish'].widget = DateInput(attrs={'type': 'date'})
        return form


class UserPostUpdateView(LoginRequiredMixin, OwnerMixin, OwnerEditMixin, UpdateView):
    model = UserPost
    fields = ["publish", "status", "title", "content"]
    template_name = "create/post_edit.html"

    def get_form(self):
        form = super().get_form()
        form.fields['publish'].widget = DateInput(attrs={'type': 'date'})
        return form
    
    # def get_context_data(self, **kwargs):
    #     context = super().get_context_data(**kwargs)
    #     context['publish'] = self.publish
    #     return context


class PostList(ListView):
    """Landing page for create app. Shows list of posts."""
    model = UserPost
    paginate_by = 2
    context_object_name = "post_list"
    template_name = "create/post_list.html"

    def get_queryset(self):
        """Return published posts (not including those set to be published in the future)."""
        return UserPost.objects.filter(publish__lte=timezone.now(), active=True, status="published").order_by('-publish')


class PostListByUser(ListView):
    """Shows list of posts by user"""
    model = UserPost
    paginate_by = 2
    context_object_name = "post_list"
    template_name = "create/post_list_by_user.html"

    def get_queryset(self):
        """Return published posts (not including those set to be published in the future or active=false)."""
        return UserPost.objects.filter(user__slug=self.kwargs['slug'], publish__lte=timezone.now(), active=True, status="published").order_by('-publish')


class PostDetail(DetailView):
    """Shows post detail."""
    model = UserPost
    context_object_name = "post_detail"
    template_name = "create/post_detail.html"
    # slug_url_kwarg = "slug"

    def get_queryset(self):
        """Return published post (not including those set to be published in the future or active=false)."""
        return UserPost.objects.filter(publish__lte=timezone.now(), active=True, status="published")


class UserPostList(LoginRequiredMixin, OwnerMixin, ListView):
    """Shows post list to user even if it is draft or unpublished"""
    model = UserPost
    context_object_name = "user_post_detail"
    template_name = "create/user_post_list.html"


class UserPostDetail(LoginRequiredMixin, OwnerMixin, DetailView):
    """Shows post detail to user even if it is draft or unpublished"""
    model = UserPost
    context_object_name = "user_post_detail"
    template_name = "create/user_post_detail.html"


class UserPostDeleteView(LoginRequiredMixin, OwnerMixin, DeleteView):
    model = UserPost
    template_name = "create/delete.html"

    def get_success_url(self, *args, **kwargs):
        return reverse_lazy('create:user_post_list', args=[self.kwargs['slug']])

#urls.py

from django.urls import path
from .views import PostList, PostListByUser, PostDetail, UserPostCreateView, UserPostList, UserPostDetail, UserPostUpdateView, UserPostDeleteView

# Refer to https://docs.djangoproject.com/en/3.2/intro/tutorial04/#amend-urlconf

app_name = "create"
urlpatterns = [
    path("collideas/", PostList.as_view(), name="index"),
    path("collideas/<slug:slug>", PostListByUser.as_view(), name="posts_by_user"),
    path("my_collidea/", UserPostCreateView.as_view(), name="post"),
    path("my_collideas/", UserPostList.as_view(), name="user_post_list"),
    path("my_collideas/<int:year>/<int:month>/<int:day>/<slug:slug>/", UserPostDetail.as_view(), name="user_post_detail"),
    path("collideas/<int:year>/<int:month>/<int:day>/<slug:slug>/", PostDetail.as_view(), name="detail"),
    path("my_collideas/<int:year>/<int:month>/<int:day>/<slug:slug>/edit/", UserPostUpdateView.as_view(), name="edit"),    
    path("my_collideas/<int:year>/<int:month>/<int:day>/<slug:slug>/delete/", UserPostDeleteView.as_view(), name="delete"),    
]

self 指的是视图,而不是对象,因此您应该使用:

class OwnerEditMixin(object):
    # …
    
    def get_success_url(self):
        return reverse_lazy(
            'create:user_post_detail',
            kwargs={
                #              ↓ use self.object
                'year': self.<strong>object</strong>.publish.year,
                'month': self.<strong>object</strong>.publish.month,
                'day': self.<strong>object</strong>.publish.day,
                'slug': self.<strong>object</strong>.slug
            }