You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中'DeferredAttribute'无'Draft'属性错误排查求助

Django AttributeError: 'DeferredAttribute' object has no attribute 'Draft' 排查与解决

错误原因

你在Post模型中,内部类Status和模型字段Status重名。Django模型字段会被注册为类的DeferredAttribute类型属性,这直接覆盖了内部定义的Status.TextChoices类。当你在视图和管理器中调用Post.Status.Draft时,实际访问的是模型字段的DeferredAttribute对象,而该对象没有Draft属性,因此触发AttributeError。

解决方法

重命名模型字段或内部类,消除命名冲突。推荐遵循Python变量命名规范,将模型字段改为小写(同时修正其他不符合规范的字段名),具体修改如下:

修改后的models.py代码

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

class PublishManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status=Post.Status.Draft)


class Post(models.Model):
    class Status(models.TextChoices):
        Draft = 'Dr', "Draft"
        Released = 'RL', "Released"
        Rejected = 'RJ', "Rejected"

    # Managers
    objects = models.Manager()
    Publishedss = PublishManager()

    # Author - 修正为小写author,符合规范
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="up")
    # 基础信息字段 - 修正为小写命名
    title = models.CharField(max_length=200)
    description = models.TextField(max_length=9000)
    slug = models.SlugField(max_length=250)
    # 时间字段 - 补充default参数,修正字段名
    published = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    # 状态字段 - 改为小写status,避免和内部类重名
    status = models.CharField(max_length=2, choices=Status.choices, default=Status.Draft)

    class Meta:
        ordering = ["-published"]
        indexes = [
            models.Index(fields=['-published'])
        ]

    def __str__(self):
        return self.title

修改后的views.py代码

from django.shortcuts import get_object_or_404, render
from .models import Post

def post_detail(request, id):
    print(id)
    posts1 = get_object_or_404(Post, id=id, status=Post.Status.Draft)

    context = {
        "Post": posts1
    }
    return render(request, "blog/detail.html", context)

额外注意事项

  • 模型字段名统一使用小写,避免与类名、内部类名冲突,符合PEP8编码规范。
  • published字段原代码缺少default=参数,会导致Django直接执行timezone.now而非将其作为默认值函数,必须补充default=。

内容的提问来源于stack exchange,提问作者Arash Raynx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:25:43