后台管理中的小功能:
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {“fields”: [“question_text”]}),
(“Date information”, {“fields”: [“pub_date”], “classes”: [“collapse”]}),
]
inlines = [ChoiceInline]
inlines
在Django的后台管理系统中,inlines是一个非常有用的功能,它允许你在一个模型的编辑页面内嵌另一个模型的编辑表单。这在处理具有外键关系的模型时特别有用,因为你可以在一个页面上编辑相关联的对象。
在你提供的代码中,inlines属性包含了一个列表,其中有一个ChoiceInline类。这意味着当你在后台编辑Question对象时,你也可以在同一个页面上编辑与该问题相关的Choice对象。
为了实现这个功能,你通常需要创建一个Inline类,这个类通常继承自admin.TabularInline或admin.StackedInline。这两者的区别主要在于展示的样式:TabularInline以表格的形式展示,而StackedInline则将每个字段垂直堆叠。
extra属性
在已添加过的,会在原有的基础上再添加extra个选项。
继承admin.TabularInline和继承admin.StackedInline的区别
展示的形式不同
通过 TabularInline (替代 StackedInline ),关联对象以一种表格式的方式展示,显得更加紧凑
作用于修改页面的字段
fieldsets
作用于列表页面(展示页面)
list_display(展示时,名称是以空格代替下划线,然后字母全大写)
list_filter(过滤器)
search_fields
装饰器
装饰器修饰的函数要和被修饰的函数写在一起(要挨着),不然description不会生效
如果@admin.display()装饰器和其下的方法(如was_published_recently)之间有其他代码或空行,装饰器就不会应用于该方法。
在Python中,装饰器应当直接放置在它要装饰的函数或方法的正上方,中间不能有其他代码或空行。这样,装饰器才能正确地应用。
Meta和Admin类
排序(ordering)
在模型的 Meta 类中定义的 ordering:这会成为模型查询的默认排序方式,无论是在 Django Admin 界面还是在你的后端代码中。换句话说,当你没有明确指定排序方式时,它会使用这个默认的排序。例如,执行 Campaign.objects.all() 会使用在 Meta 类中定义的 ordering。
在 Admin 类中定义的 ordering:这仅影响 Django Admin 界面上的对象列表视图。这是一个 Admin-specific 的设置,会覆盖模型 Meta 类中的默认 ordering,但仅限于 Admin 界面。
举例来说:
如果你在 Campaign 的 Meta 类中定义了 ordering = [‘-sort_order’, ‘id’],然后你执行 Campaign.objects.all(),结果会按照 sort_order 降序和 id 升序排序。
但如果你同时在 CampaignAdmin 中定义了 ordering = [‘-date_added’],那么当你在 Django Admin 界面上查看 Campaign 对象列表时,它们会按照 date_added 降序排列,而不是 sort_order。
简而言之,模型的 Meta 类中的 ordering 定义了一个全局的默认排序,而在 Admin 类中的 ordering 提供了一个特定于 Admin 界面的排序,会覆盖模型默认的排序(仅在 Admin 界面)。
外键引用位置问题
如果Campaign模型需要引用PubApp作为一个外键,而PubApp模型在Campaign模型之后被定义。在ForeignKey中使用了字符串’PubApp’来引用PubApp模型,而不是直接使用PubApp类。这样Django就知道你想引用的是哪个模型,即使它在当前位置尚未定义。
使用字符串形式的模型引用可以避免重新排列模型的定义顺序,这是一个非常实用的特性。
报错:添加一个新的非空字段
D:\gitprojects\offerwall08\yosemite>python manage.py makemigrations
It is impossible to add a non-nullable field ‘pubapp’ to campaign without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
- Provide a one-off default now (will be set on all existing rows with a null value for this column)
- Quit and manually define a default value in models.py.
Select an option:
这个消息表示你正在尝试在 Campaign 模型中添加一个新的非空字段 pubapp,但由于数据库中已经存在 Campaign 的数据,并且新字段没有指定默认值,所以Django不知道应该为现有记录中的这个新字段填充什么值。
为了解决这个问题,Django为你提供了以下选项:
现场提供一个一次性的默认值:这个值将被设置为所有现有记录的新字段的值。这是一个快速解决方案,但要注意,如果你的字段是外键,提供一个默认值可能不是一个好主意,除非你确定某个默认的外键对象确实存在并且适合作为默认值。
退出并在 models.py 中手动定义一个默认值:这允许你先退出,然后在模型定义中为新字段指定一个默认值。这样,当你再次运行 makemigrations 时,Django将使用这个默认值。
对于外键字段,一个常见的方法是:
允许该字段在数据库中为NULL,即设置 null=True。这样,当你运行 makemigrations 时,现有的记录会为这个字段设置一个NULL值。然后,你可以随时更新这些记录以设置适当的外键关系。
Code:
pubapp = models.ForeignKey(‘PubApp’, on_delete=models.CASCADE, null=True)
之后,如果你希望该字段为非空,可以再次修改模型(例如,设置null=False),然后为所有记录提供适当的外键值,并再次运行 makemigrations 和 migrate。
上传图片
image= models.ImageField(upload_to=‘iconImage/’,verbose_name=‘Icon Image’)
配置
settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR, ‘media/’)
MEDIA_URL = ‘/media/’
urls.py:
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
一些重要的参数和设置
MEDIA_ROOT、MEDIA_URL 以及在 urls.py 中的相关设置是处理 Django 上传的媒体文件时非常重要的。
简单来说:
MEDIA_ROOT: 这是在服务器上存储上传的媒体文件的物理路径。当用户上传文件时,这些文件将被存储在这个目录下。
MEDIA_URL: 这是访问这些媒体文件时的基础 URL。它定义了如何在网页中引用这些文件的 URL。
urlpatterns 的设置:在开发时,Django 内置的开发服务器并不默认地为媒体文件提供服务。这段代码告诉 Django 的开发服务器如何为 MEDIA_URL 下的请求提供服务,并将它们映射到 MEDIA_ROOT 目录下的相应文件。
这些设置的目的是在开发环境中,确保你能够正常上传、存储并在网页中显示媒体文件(如图片)。
在生产环境中,你可能会使用更高效的服务器(如 Nginx 或 Apache)来处理媒体文件的静态服务,而不是依赖 Django。但在开发过程中,这些设置对于测试和验证功能是非常有用的。
如果你打算在开发环境中处理和显示上传的媒体文件,那么这些设置是必要的。