在Django admin的change_form中的两个模型字段之间添加自定义html

时间:2011-06-04 23:17:20

标签: python django django-admin

假设我有两个模型:

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)  

是否有一种很好的方法可以在库change_form模板中的名称和地址之间添加一些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_fields 1,'name'不是PresupuestoAdmin'的可调用属性或属性'或者发现在'Presupuesto'模型中。似乎“名称”字段未添加到管理员使用的表单中。

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 个答案:

答案 0 :(得分:9)

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)

答案 1 :(得分:2)

这可能无法完全满足您的需求,但您可以通过将此bar添加到Foo来覆盖模型admin.py中字段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) 的窗口小部件:

{{1}}

答案 2 :(得分: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',)