在Django ModelAdmin中,如何允许编辑ForeignKey对象但不能重新分配?

时间:2018-06-13 13:12:06

标签: django

我使用的结构可以像这样简化:

# models.py
class Order(models.Model):
    payment = models.ForeignKey('Payment', null=True, on_delete=models.PROTECT)
    # other fields

class Payment(models.Model):
    # fields

# admin.py
@admin.register(Payment)
class PaymentAdmin(admin.ModelAdmin):
    model = Payment
    fields = (...)
    readonly_fields = (...)

    def get_model_perms(self, request):
        return {}

    def has_delete_permission(self, request, obj=None):
        return False

    def has_add_permission(self, request):
        return False

@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    model = Order
    fields = ('payment', ...)

现在,我想要做的是通过点击铅笔图标,允许Payment对象从OrderAdmin中的弹出窗口进行编辑。但是,我不想让管理员重新分配(例如,将关联的付款从PaymentObject(1)更改为PaymentObject(2)null)。由于我希望能够修改payment,因此我无法将payment字段标记为只读。

我无法更改ForeignKey关系,因为这需要巨大的重构。我更喜欢只处理表单的解决方案,但即使是一个hacky也比我想的更好。

2 个答案:

答案 0 :(得分:0)

I found a way. It's not exactly what I had in mind, but it does the job: I rendered the payment field as a link to payment admin:

 @admin.register(Order)
 class OrderAdmin(admin.ModelAdmin):
     model = Order
     fields = ('display_payment', ...)
     read_only_fields = ['display_payment']

    def display_payment(self, obj):
        payment_url = reverse('admin:appname_payment_change', args=(obj.payment.id,))
         return format_html('<a href="{}">{}</a>', payment_url, str(obj.payment))
    display_payment.short_description = 'Payment'

答案 1 :(得分:0)

https://books.agiliq.com/projects/django-admin-cookbook/en/latest/changeview_readonly.html

尝试一下

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):
    ...
    readonly_fields = ["father", "mother", "spouse"]