Встроенный набор форм в Django - удаление определенных полей

Мне нужно создать встроенный набор форм, который

a) исключает отображение некоторых полей из MyModel вообще

b) отображает некоторые поля MyModel, но не позволяет их редактировать.

Я попытался использовать приведенный ниже код, используя values(), чтобы отфильтровать набор запросов только для тех значений, которые я хотел вернуть. Однако это не удалось.

Кто-нибудь с какой-либо идеей?

class PointTransactionFormset(BaseInlineFormSet):
    def get_queryset(self):
        qs = super(PointTransactionFormset, self).get_queryset()
        qs = qs.filter(description="promotion feedback")
        qs = qs.values('description','points_type') # this does not work
        return qs

class PointTransactionInline(admin.TabularInline):
    model = PointTransaction
    #formset = points_formset()
    #formset = inlineformset_factory(UserProfile,PointTransaction)
    formset = PointTransactionFormset

Ответ 1

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

PersonFormSet = inlineformset_factory(User, Person, form=PersonForm, extra=6)

Это позволяет выполнять все проверки формы, исключает и т.д. на уровне модели и копировать ее factory.

Ответ 2

Это набор форм для использования в админ? Если это так, просто установите " exclude= ['field1', 'field2']" на свой InlineModelAdmin, чтобы исключить поля. Чтобы показать некоторые значения полей uneditable, вам нужно будет создать простой пользовательский виджет, метод render() которого просто вернет значение, а затем переопределит метод formfield_for_dbfield(), чтобы назначить ваш виджет соответствующим полям.

Если это не для администратора, а для набора форм для использования в другом месте, то вы должны сделать вышеуказанные настройки (исключить атрибут в внутреннем классе Meta, переопределить виджет в методе __init__) в подклассе ModelForm, который вы передаете в набор форм конструктор. (Если вы используете Django 1.2 или новее, вы можете просто использовать readonly_fields).

Я могу обновить примеры кода, если вы уточните, в какой ситуации вы находитесь (admin или нет).

Ответ 3

У меня была аналогичная проблема (не для администратора - для сайта, ориентированного на пользователя), и обнаружил, что вы можете передать набор форм и поля, которые хотите отобразить, в inlineformset_factory следующим образом:

factory = inlineformset_factory(UserProfile, PointTransaction, 
                formset=PointTransactionFormset,
                fields=('description','points_type'))
formset = factory(instance=user_profile, data=request.POST)

где user_profile является UserProfile.

Следует предупредить, что это может вызвать проблемы проверки, если базовая модель имеет обязательные поля, которые не включены в список полей, переданных в inlineformset_factory, но это случай для любого вида формы.