Django скрывает поле при создании нового объекта

#python #django

#python #django

Вопрос:

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

 class Toys(BaseModel):
    name = models.CharField(max_length=255)
    tags = models.ManyToManyField(Tag, related_name='Item_tags')
    price = models.CharField(max_length=255)
    status = models.BooleanField(default=False)
 

Комментарии:

1. Один из способов сделать это — скрыть использование CSS с использованием имен классов

2. я хочу скрыть это поле в панели администратора django. есть какие-нибудь другие способы?

Ответ №1:

В администраторе модели, который вы регистрируете в своем admin.py файле, вы можете перегрузить get_form(self, request, obj=None, **kwargs) метод. Как вы можете видеть, он принимает аргумент obj, он используется None только при добавлении (не None при изменении). Оттуда вы можете возиться с формой, чтобы исключить из нее поле формы «name», только если obj is None .

В Django 1.10 этот метод django.contrib.admin.options.ModelAdmin.get_form включен .

РЕДАКТИРОВАТЬ 1 (это далеко не лучшее решение) Я не могу дать вам полное решение здесь, но вы можете начать с чего-то вроде:

 # admin.py

from django.contrib import admin

from models import Toys


class ToysModelAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        # all the code you have in the original
        # django.contrib.admin.options.ModelAdmin.get_form
        # up to the last try except

        if obj is not None:
            defaults['fields'] = ('tags', 'price', 'status', )

        try:
            return modelform_factory(self.model, **defaults)
        except FieldError as e:
            raise FieldError(
                '%s. Check fields/fieldsets/exclude attributes of class %s.'
                % (e, self.__class__.__name__)
            )

admin.site.register(Toys, ToysModelAdmin)
 

РЕДАКТИРОВАТЬ 2 (это лучший пример)

 # admin.py

from collections import OrderedDict

from django.contrib import admin

from models import Toys


class ToysModelAdmin(admin.ModelAdmin):

    # this is not perfect as you'll need to keep track of your
    # model changes also here, but you won't accidentally add
    # a field that is not supposed to be editable
    _add_fields = ('tags', 'price', 'status', )

    def get_form(self, request, obj=None, **kwargs):
        model_form = super(ToysModelAdmin, self).get_form(
            request, obj, **kwargs
        )

        if obj is None:
            model_form._meta.fields = self._add_fields
            model_form.base_fields = OrderedDict(**[
                (field, model_form.base_fields[field])
                for field in self._add_fields
            ])

        return model_form
 

Комментарии:

1. можете ли вы показать мне на примере. я отредактировал свой вопрос с помощью примера

2. Посмотрите мое РЕДАКТИРОВАНИЕ 2, я кратко протестировал его, надеюсь, оно сработает для вас.

3. одна из проблем заключается в упорядочении имен полей по алфавиту, как я могу это исправить?

4. Я не понимаю, вы не хотите упорядочить в алфавитном порядке или нет? Это OrderedDict означает, что порядок полей устанавливается после установки в нем ключа. Чтобы изменить этот порядок, вы, возможно, захотите переопределить model_form.base_fields . Для более сложного решения вам придется задать другой вопрос, поскольку он на самом деле не связан с этим.

5. он упорядочил названия полей в алфавитном порядке, но я хочу оставить их такими, какими они были обычными.