Подтвердить что ты не робот

Django admin: сделать поле редактируемым в добавить, но не редактировать

У меня есть модель, подобная этой:

class Product(models.Model):
    third_party_id = models.CharField(max_length=64, blank=False, unique=True)

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

4b9b3361

Ответ 1

Не устанавливайте self.readonly_fields, чтобы избежать проблем с потоком. Вместо этого переопределите метод get_readonly_fields:

def get_readonly_fields(self, request, obj=None):
    if obj: # obj is not None, so this is an edit
        return ['third_party_id',] # Return a list or tuple of readonly fields' names
    else: # This is an addition
        return []

Ответ 2

Это полезно (ответ shanyu с использованием get_readonly_fields), однако он не работает должным образом, если используется в "StackedInline". Результат - две копии любого поля, помеченного как readonly, и он не редактируется в экземпляре "add". Смотрите эту ошибку: https://code.djangoproject.com/ticket/15602

Надеюсь, это поможет кому-то найти!

Ответ 3

Я не уверен, что это лучший способ, но вы можете определить свою собственную форму для администратора. И custom validate your third_party_id, отклоняя, если он уже установлен:

Admin.py

class ProductAdminForm(forms.ModelForm):
    class Meta:
        model = Product

    def clean_third_party_id(self):
        cleaned_data = self.cleaned_data
        third_party_id = cleaned_data['third_party_id']
        id = cleaned_data['id']
        obj = Product.objects.get(id=id)
        if obj.third_party_id != third_party_id:
            raise ValidationError("You cannot edit third_party_id, it must stay as %s" % obj.third_party_id)
         return third_party_id


class ProductAdmin(admin.Admin):
    form = [ProductAdminForm,]