如何继承ForeignKey扩展模型字段?

How to inherit from ForeignKey to extend model field?

我正在尝试创建自定义外键。我继承了它并试图覆盖 __init__ 方法来提供位置参数 toon_delete 如下所示:

from django.contrib.auth.models import User

class CurrentUserField(models.ForeignKey):
    def __init__(self, **kwargs):
        super().__init__(User, models.CASCADE, **kwargs)


class DemoModel(models.Model):
    owner = CurrentUserField()
    info = models.TextField()

当我 运行 makemigrations:

时出现以下错误
TypeError: __init__() got multiple values for argument 'on_delete'

我似乎无法弄清楚问题出在哪里。我只为两个位置参数提供两个值。

假设如果您在所有者字段本身中传递 Useron delete 参数,您可以看到 Django 如何转换其参数。

例子

from django.db import models
from django.contrib.auth.models import User


class CurrentUserField(models.ForeignKey):
    def __init__(self, *args, **kwargs):
        for i in args:
            print(i, "This is an argument")

        for j in kwargs.items():
            print(j, "This is a keyword argument")
        super().__init__(*args, **kwargs)


class DemoModel(models.Model):
    owner = CurrentUserField(User, on_delete=models.CASCADE)
    info = models.TextField()

输出

<class 'django.contrib.auth.models.User'> This is an argument
('on_delete', <function CASCADE at 0x103900400>) This is a keyword argument
('on_delete', <function CASCADE at 0x103900400>) This is a keyword argument
('to', 'auth.User') This is a keyword argument
('on_delete', <function CASCADE at 0x103900400>) This is a keyword argument
('to', 'auth.User') This is a keyword argument

如您所见,Django 正在将 auth.Usermodels.CASCADE 转换为分别具有键 toon_delete 的字典。即 {'to': 'auth.User', 'on_delete': <function CASCADE at 0x103900400>}.

因此,在您的情况下,您应该为键 toon_delete 设置默认值以获得预期的行为。

from django.db import models
from django.contrib.auth.models import User


class CurrentUserField(models.ForeignKey):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('to', User)
        kwargs.setdefault('on_delete', models.CASCADE)
        super().__init__(*args, **kwargs)


class DemoModel(models.Model):
    owner = CurrentUserField()
    info = models.TextField()