Skip to main content
 首页 » 编程设计

python之如何在 Django 中自定义 related_name 参数

2024年09月07日35webabcd

我有一个抽象模型和两个子模型,例如:

class Invoice(models.Model): 
    user = models.ForeignKey("User", related_name='%(class)s') 
 
    class Meta: 
        abstract=True 
 
class SaleInvoice(Invoice): 
    field_sale = models.CharField(max_length=255) 
 
class PurchaseInvoice(Invoice): 
    field_purchase = models.CharField(max_length=255) 

现在子模型的反向名称将是 saleinvoices 和 purchaseinvoices。但我需要的是 sale_invoices 和 purchase_invoices。如何做到这一点? CamelCase 之间的下划线。

请您参考如下方法:

  1. 覆盖 ForeignKey 的 contribute_to_class() 以设置 related_name.
class CustomFk(models.ForeignKey): 
    <b>def contribute_to_class(self, cls, name, private_only=False, **kwargs): 
        super().contribute_to_class(cls, name, private_only=False, **kwargs) 
        self.remote_field.related_name = "_".join(re.findall('[A-Z][^A-Z]*', cls.__name__))</b>


2. 在抽象模型中使用此自定义 FK 字段。

class Invoice(models.Model): 
    <b>user = CustomFk(User, related_name='%(class)s')</b> 
 
    class Meta: 
        abstract = True



# migrations file 
operations = [ 
    migrations.CreateModel( 
        name='PurchaseInvoice', 
        fields=[ 
            ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 
            ('field_purchase', models.CharField(max_length=255)), 
            ('user', sample.models.CustomFk(on_delete=django.db.models.deletion.CASCADE, 
                                            <b>related_name='Purchase_Invoice',</b> to=settings.AUTH_USER_MODEL)), 
        ], 
        options={ 
            'abstract': False, 
        }, 
    ), 
    migrations.CreateModel( 
        name='SaleInvoice', 
        fields=[ 
            ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 
            ('field_sale', models.CharField(max_length=255)), 
            ('user', sample.models.CustomFk(on_delete=django.db.models.deletion.CASCADE, 
                                            <b>related_name='Sale_Invoice',</b> to=settings.AUTH_USER_MODEL)), 
        ], 
        options={ 
            'abstract': False, 
        }, 
    ), 
]

引用
*。 contribute_to_class()
*。 Split string with uppercase letters- Python