Django admin:在add中使字段可编辑,但不编辑

时间:2022-06-01 18:58:35

I've got a model similar to this:

我有一个类似的模型:

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

that uses the Django default primary key. I want users to be able to add products by setting the third_party_id on the add page, but I don't want that field editable in the edit page to avoid corrupting the third_party_id. In the Django docs, the same settings appear to be used for add and edit. Is this possible?

它使用Django缺省主键。我希望用户能够通过在添加页面上设置third_party_id来添加产品,但我不希望编辑页面中的字段可编辑,以避免损坏third_party_id。在Django文档中,用于添加和编辑的设置是相同的。这是可能的吗?

3 个解决方案

#1


44  

Do not set self.readonly_fields to avoid thread issues. Instead override get_readonly_fields method:

不自我。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


5  

The above is helpful (shanyu's answer using get_readonly_fields), however it does not work properly if used in "StackedInline". The result is two copies of whatever field is marked readonly, and it is not editable in the "add" instance. See this bug: https://code.djangoproject.com/ticket/15602

上面的内容很有帮助(shanyu使用get_readonly_fields的回答),但是如果在“StackedInline”中使用,则不能正常工作。结果是,无论哪个字段被标记为只读,它都是两个副本,在“添加”实例中是不可编辑的。看到这个错误:https://code.djangoproject.com/ticket/15602

Hope this saves someone some searching!

希望这能节省一些搜索!

#3


0  

I am not sure if this is the best way, but you could define your own form for the admin. And custom validate your third_party_id, rejecting if it is already set:

我不确定这是否是最好的方式,但是您可以为管理员定义自己的表单。自定义验证您的third_party_id,如果已经设置,则拒绝:

Admin.py

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,]

#1


44  

Do not set self.readonly_fields to avoid thread issues. Instead override get_readonly_fields method:

不自我。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


5  

The above is helpful (shanyu's answer using get_readonly_fields), however it does not work properly if used in "StackedInline". The result is two copies of whatever field is marked readonly, and it is not editable in the "add" instance. See this bug: https://code.djangoproject.com/ticket/15602

上面的内容很有帮助(shanyu使用get_readonly_fields的回答),但是如果在“StackedInline”中使用,则不能正常工作。结果是,无论哪个字段被标记为只读,它都是两个副本,在“添加”实例中是不可编辑的。看到这个错误:https://code.djangoproject.com/ticket/15602

Hope this saves someone some searching!

希望这能节省一些搜索!

#3


0  

I am not sure if this is the best way, but you could define your own form for the admin. And custom validate your third_party_id, rejecting if it is already set:

我不确定这是否是最好的方式,但是您可以为管理员定义自己的表单。自定义验证您的third_party_id,如果已经设置,则拒绝:

Admin.py

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,]