I have read a lot of questions related to clashes reverse accessor
but nothing seems to help me.
I'm trying to customize the Token
field in DRF
to be able to add some fields to it (I would like to have a Token
per Company
and Companies
can create FiscalEntities
and each FiscalEntity
will have its own Token
)
I have followed the following question: How to use custom token model in Django Rest Framework
core/models
from django.db import models
from django.utils.translation import ugettext_lazy as _
from rest_framework import authentication
from company.models import Company
from fiscalentity.models import FiscalEntity
class CustomAuthenticationToken(models.Model):
"""
The default authorization token model.
"""
key = models.CharField(_("Key"), max_length=40, primary_key=True)
company = models.OneToOneField(
Company, related_name='auth_token',
on_delete=models.CASCADE, verbose_name=_("Company")
)
created = models.DateTimeField(_("Created"), auto_now_add=True)
# Fiscal entity can be null because if it is null this token belongs to the parent Company
fiscal_entity = models.ForeignKey(FiscalEntity, null=True, on_delete=models.CASCADE)
class Meta:
verbose_name = _("Token")
verbose_name_plural = _("Tokens")
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super(CustomAuthenticationToken, self).save(*args, **kwargs)
@staticmethod
def generate_key():
return binascii.hexlify(os.urandom(20)).decode()
def __str__(self):
return self.key
class BearerAuthentication(authentication.TokenAuthentication):
"""
Simple token based authentication using utvsapitoken.
Clients should authenticate by passing the token key in the 'Authorization'
HTTP header, prepended with the string 'Bearer '. For example:
Authorization: Bearer 956e252a-513c-48c5-92dd-bfddc364e812
"""
keyword = 'Bearer'
model = CustomAuthenticationToken
core/authentication
from rest_framework.authentication import TokenAuthentication
from core.models import CustomAuthenticationToken
class CustomTokenAuthentication(TokenAuthentication):
model = CustomAuthenticationToken
app/settings
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
'core',
...
]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 5,
'DEFAULT_AUTHENTICATION_CLASSES': (
'core.models.BearerAuthentication',
'core.authentication.CustomTokenAuthentication'
),
}
AUTHENTICATION_BACKENDS = [
'core.models.BearerAuthentication',
]
Trying to run the migrations I get the following errors:
authtoken.Token.user: (fields.E304) Reverse accessor for 'Token.user' clashes with reverse accessor for 'CustomAuthenticationToken.company'.
HINT: Add or change a related_name argument to the definition for 'Token.user' or 'CustomAuthenticationToken.company'.
authtoken.Token.user: (fields.E305) Reverse query name for 'Token.user' clashes with reverse query name for 'CustomAuthenticationToken.company'.
HINT: Add or change a related_name argument to the definition for 'Token.user' or 'CustomAuthenticationToken.company'.
core.CustomAuthenticationToken.company: (fields.E304) Reverse accessor for 'CustomAuthenticationToken.company' clashes with reverse accessor for 'Token.user'.
HINT: Add or change a related_name argument to the definition for 'CustomAuthenticationToken.company' or 'Token.user'.
core.CustomAuthenticationToken.company: (fields.E305) Reverse query name for 'CustomAuthenticationToken.company' clashes with reverse query name for 'Token.user'.
HINT: Add or change a related_name argument to the definition for 'CustomAuthenticationToken.company' or 'Token.user'.
I have tried omitting the
company = models.OneToOneField(
Company, related_name='auth_token',
on_delete=models.CASCADE, verbose_name=_("Company")
)
but doing so I get a new error saying Invalid field name(s) given in select_related: 'user'. Choices are: (fiscal_entity)
Thank you for your help in advance