Django: Подделка поля в интерфейсе администратора? - PullRequest
14 голосов
/ 03 февраля 2011

У меня есть модель, Foo. Он имеет несколько свойств базы данных и несколько свойств, которые рассчитываются на основе комбинации факторов. Я хотел бы представить эти рассчитанные свойства пользователю, как если бы они были свойствами базы данных. (Коэффициенты поддержки будут изменены, чтобы отражать ввод данных пользователем.) Есть ли способ сделать это с помощью интерфейса администратора Django?

Ответы [ 4 ]

30 голосов
/ 04 февраля 2011

Я бы предложил вам создать подкласс модели формы для Foo (FooAdminForm), чтобы добавить свои собственные поля, не поддерживаемые базой данных.Ваша пользовательская проверка может находиться в clean_* методах ModelForm.

Внутри save_model метода FooAdmin вы получаете запрос, экземпляр Foo и данные формы, так что вы можете сделатьвся обработка данных до / после сохранения экземпляра.

Вот пример модели с пользовательской формой, зарегистрированной администратором django:

from django import forms
from django.db import models
from django.contrib import admin


class Foo(models.Model):
    name = models.CharField(max_length=30)


class FooAdminForm(forms.ModelForm):
    # custom field not backed by database
    calculated = forms.IntegerField()

    class Meta:
        model = Foo 


class FooAdmin(admin.ModelAdmin):
    # use the custom form instead of a generic modelform
    form = FooAdminForm

    # your own processing
    def save_model(self, request, obj, form, change):
        # for example:
        obj.name = 'Foo #%d' % form.cleaned_data['calculated'] 
        obj.save()


admin.site.register(Foo, FooAdmin)

Предоставлениеначальные значения для настраиваемых полей на основе данных экземпляра

(я не уверен, что это лучшее решение, но оно должно работать.)

Когда модель формирует существующую модельэкземпляр в базе данных создан, ему передается этот экземпляр.Таким образом, в __init__ FooAdminForm можно изменять атрибуты полей на основе данных экземпляра.

    def __init__(self, *args, **kwargs):
        # only change attributes if an instance is passed            
        instance = kwargs.get('instance')
        if instance:
            self.base_fields['calculated'].initial = (instance.bar == 42)
        forms.ModelForm.__init__(self, *args, **kwargs)
4 голосов
/ 23 марта 2011

Достаточно просто получить произвольные данные для отображения в списке изменений или заставить поле отображаться в форме: list_display произвольно принимает либо фактические свойства модели, либо методы, определенные в модели или modeladmin, и вы можете создавать подклассыforms.ModelForm чтобы добавить любой тип поля, который вы хотели бы добавить в форму изменения.

Гораздо сложнее / невозможно объединить их, то есть иметь произвольный фрагмент данных в списке изменений, который вы можете редактировать вместо, указав list_editable.Кажется, что Django принимает только истинное свойство модели, соответствующее полю базы данных.(даже использования @property для метода в определении модели недостаточно).

Кто-нибудь нашел способ отредактировать поле, фактически отсутствующее в модели, прямо со страницы списка изменений?

1 голос
/ 12 февраля 2011

Вы можете использовать @property декоратор в вашей модели (Python> = 2.4):

class Product(models.Model):

    @property
    def ranking(self):
        return 1

«ранжирование» может быть использовано в list_display:

class ProductAdmin(admin.ModelAdmin):
    list_display = ('ranking', 'asin', 'title')
1 голос
/ 04 февраля 2011

В форме редактирования введите имя свойства в readonly_fields (только 1.2 и выше).

В списке изменений поместите его в list_display .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...