Reputation: 5800
I am trying to create a custom ForeignKey. I have inherited from it and trying to override __init__
method to provide the positional arguments to
and on_delete
like the following:
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()
It gives me the following error when I am running makemigrations
:
TypeError: __init__() got multiple values for argument 'on_delete'
I can't seem to figure out what the problem is. I am only providing two values for two positional arguments.
Upvotes: 5
Views: 1054
Reputation: 24562
Suppose if you pass User
and on delete
parameters in your owner field itself you could see how Django is converting its arguments.
EXAMPLE
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()
OUTPUT
<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
as you can see Django is converting auth.User
and models.CASCADE
into a dictionary with keys to
and on_delete
respectively. i.e., {'to': 'auth.User', 'on_delete': <function CASCADE at 0x103900400>}
.
So in your case you should set the default value for the keys to
and on_delete
to get the expected behaviour.
i.e.,
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()
Upvotes: 4