formfield_for_foreignkey怎么使用,请以书籍和作者为例进行说明
时间: 2024-03-28 14:42:33 浏览: 129
假设有两个 Django 模型,一个是 Book,另一个是 Author,它们之间是一对多的关系,即一个作者可以写多本书。现在我们需要在 Book 的 admin 页面中添加一个 inline 的 Author 表单,允许用户在创建 Book 记录时同时选择或创建一个 Author 记录。同时,我们需要对输入的作者姓名进行合法性检查,如果作者姓名为空或者已经存在,则需要在输入框上方显示相应的错误信息。
为了实现这个功能,我们可以在 Book 的 admin.py 文件中定义一个自定义的 inline 类,重写其中的 formfield_for_foreignkey 方法,如下所示:
```python
from django.contrib import admin
from django.forms import ValidationError
from .models import Book, Author
class AuthorInline(admin.TabularInline):
model = Author
extra = 0
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'name':
kwargs['widget'] = forms.TextInput(attrs={'placeholder': '请输入作者姓名'})
if db_field.name == 'name' and request.method == 'POST':
name = request.POST.get('author_set-0-name', '')
if not name:
raise ValidationError('作者姓名不能为空')
if Author.objects.filter(name=name).exists():
raise ValidationError('该作者已经存在')
return super().formfield_for_foreignkey(db_field, request, **kwargs)
class BookAdmin(admin.ModelAdmin):
inlines = [AuthorInline]
admin.site.register(Book, BookAdmin)
admin.site.register(Author)
```
在这段代码中,我们首先定义了一个 AuthorInline 类,作为 Book 的 inline 表单。在 formfield_for_foreignkey 方法中,我们对 name 字段进行了特判,设置了一个 placeholder 属性,用于在输入框中显示提示信息。同时,我们通过 request.POST.get 方法获取了用户输入的作者姓名,并对其进行了合法性检查。如果作者姓名为空或者已经存在,则抛出一个 ValidationError 异常。最后,我们调用了父类的 formfield_for_foreignkey 方法,返回一个带有错误信息的 FormField 对象,用于在输入框上方显示错误信息。
这样,当用户在 Book 的 admin 页面中创建一条记录时,如果输入的作者姓名为空或者已经存在,则会在输入框上方显示相应的错误信息。
阅读全文