在Django管理后台的change_form中在两个模型字段之间添加自定义HTML

6 投票
3 回答
7695 浏览
提问于 2025-04-16 18:58

假设我有两个模型:

class Book(models.Model):
    name = models.CharField(max_length=50)
    library = models.ForeignKeyField('Library')

class Library(models.Model):
    name = models.CharField(max_length=50)   
    address = models.CharField(max_length=50)  
    tel = models.CharField(max_length=50)  

有没有什么好的方法可以在图书馆的修改表单模板中,在名字和地址之间添加一些HTML(一个只读的输入框)呢?我现在是通过重写admin/includes/fieldset.html来实现,但这样做有点乱,我找不到一个合适的方法来精确地显示我想要的HTML。例如,如果我想在名字字段下面添加一个显示图书馆拥有书籍数量的HTML,我会这样做:

{% for field in line %}
    ...
    {% if field.field.name == 'name' %}
        {{ field.field }}
        <div class="form-row total_books">
            <div>
                <label for="total_books">Total books:</label>
                <input type="text" maxlength="10" name="totbooks" id="totbooks" readonly="readonly">
            </div>
       </div>
    {% else %}
        {{ field.field }}
    {% endif %}
    ...
{% endfor %}

新的解决方案:

我找到了一种更好的方法,但我不知道为什么会出现这个错误:“PresupuestoAdmin.readonly_fields1,'name' 不是可调用的或 PresupuestoAdmin 的属性,也没有在模型 'Presupuesto' 中找到。”看起来 'name' 字段没有被添加到管理员使用的表单中。

class FoooAdminForm(forms.ModelForm): 
    name = models.CharField(max_length=100) 
    class Meta: 
        model = Foo 

class FooAdmin(admin.ModelAdmin): 
    form = FooAdminForm 
    fieldsets = ( 
        (None, { 'fields': ('id', 'name', 'date')}), 
    ) 
    readonly_fields = ('id', 'name') 

admin.site.register(Foo, FooAdmin) 

3 个回答

3

这可能不完全符合你的需求,但你可以通过在你的 admin.py 文件中添加以下内容,来重写模型 Foo 中字段 bar 的小部件:

from django import forms
from django.contrib import admin
from django.contrib.admin import site
from django.contrib.admin.widgets import AdminTextInputWidget
from django.utils.safestring import mark_safe
from models import Foo

class AdminFooWidget(AdminTextInputWidget):
    def render(self, name, value, attrs=None):
        s = super(AdminTextInputWidget, self).render(name, value, attrs)
        return mark_safe(s+u'<br/><b>Hello world!</b>')

class FooAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(FooAdminForm, self).__init__(*args, **kwargs)
        self.fields['bar'].widget = AdminFooWidget()

class FooAdmin(admin.ModelAdmin):
    form = FooAdminForm     

site.register(Foo, FooAdmin)
12

models.py:

class Library(models.Model):
    name = models.CharField(max_length=50)   
    address = models.CharField(max_length=50)  
    tel = models.CharField(max_length=50)

    def book_count(self):
      return self.book_set.count()

admin.py:

class LibraryAdmin(admin.ModelAdmin): 
    fieldsets = ( 
        (None, { 'fields': ('name', 'book_count', 'address', 'tel' )}), 
    ) 
    readonly_fields = ('book_count',) 

admin.site.register(Library, LibraryAdmin)
2

在编程中,有时候我们会遇到一些问题,尤其是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,但其实很多时候,解决这些问题的方法是比较简单的。

比如说,当你在写代码的时候,如果出现了错误,首先要做的就是仔细检查你的代码。看看有没有拼写错误,或者是用错了某些符号。很多时候,错误就藏在这些小细节里。

另外,了解你使用的工具或库的文档也是非常重要的。文档里通常会有很多有用的信息,比如如何正确使用某个功能,或者是常见问题的解决办法。多花点时间去阅读这些文档,可以帮助你避免很多不必要的错误。

如果你还是解决不了问题,可以考虑在网上搜索一下,看看有没有人遇到过类似的情况。很多时候,别人已经解决了你所遇到的问题,分享在网上的经验可以给你带来很大的帮助。

总之,遇到问题不要慌,慢慢来,仔细检查,善用文档和网络资源,通常都能找到解决办法。

class FooAdminForm(forms.ModelForm):
    name = forms.CharField(max_length=100, 
                widget=forms.TextInput(attrs={'readonly': 'readonly'}))

    def __init__(self, *args, **kwargs): 
        super(FooAdminForm, self).__init__(*args, **kwargs)
        self.fields['name'].required = False
        if kwargs.has_key('instance'): 
            instance = kwargs['instance'] 
            # do something with the instance here if you want 

    class Meta:
        model = Foo

class FooAdmin(admin.ModelAdmin):
    form = FooAdminForm

    fieldsets = (
        (None, {
            'fields': ('id', 'name',),})
    )
    readonly_fields = ('id',) 

撰写回答