0

I have a user model something like this

class Role(models.Model):

    ROLE_CHOICES = (
        ('agent', 'Agent'),
        ('agency', 'Agency'),
        ('manufacturer', 'Manufacturer'),
    )
    role = models.CharField(max_length=15, choices=ROLE_CHOICES)

    def __str__(self):
        return 'role'


class User(AbstractUser):

    role = models.ForeignKey(
        Role,
        on_delete=models.CASCADE,
        blank=True,
        null=True)

    def __str__(self):
        return str(self.id)

The user can be of 3 types. But at the time of registration, the user should be created with the role of agent.The endpoint for the user registration is /rest-auth/registration. This will create only a normal user with username and password. But i need to create the agent role as well. I believe, it should be done in save method of rest-auth registration serializer but I don't know how to customize the registration serializer. Can anyone shed me the light, please?

milan
  • 2,409
  • 2
  • 34
  • 71
  • You can try setting default value in foreign key like this https://stackoverflow.com/questions/9311996/setting-default-value-for-foreign-key-attribute - so when a new object gets created, a new value will be assigned. – dmitryro Jul 12 '18 at 01:34

2 Answers2

1

You can done it several ways.

Method 1

Use a callable default function on model:

def get_defaul_role():
    role, created = Role.objects.get_or_create(role='agent')
    return role</b>

class User(AbstractUser):
    role = models.ForeignKey(Role, on_delete=models.CASCADE, <b>default=get_defaul_role</b>)

    def __str__(self):
        return str(self.id)

Method 2

By overriding save() method

class User(AbstractUser):
    role = models.ForeignKey(Role, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return str(self.id)

    def save(self, *args, **kwargs):
        if not self.pk: # If instance is created
            self.role, created = Role.objects.get_or_create(role='agent')
        return super().save(*args, **kwargs)

Reference : Django's get_or_create()

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
JPG
  • 82,442
  • 19
  • 127
  • 206
  • do i still need default when overriding save() method? – milan Jul 12 '18 at 09:28
  • No...you can use **either** `Method-1` or `Method-2` – JPG Jul 12 '18 at 09:43
  • before i did not use to get csrf issue but now I am getting csrf issue when posting data in rest-auth/registration. – milan Jul 12 '18 at 10:11
  • Anyway, ask a new question in SO. (comment that url here, so I could give a try) or [go through similar question](https://www.google.co.in/search?q=csrf+verification+failed.+request+aborted.+DRF+site:stackoverflow.com&sa=X&ved=2ahUKEwiY7sTLqpncAhWJuo8KHbtvCqwQrQIoBDAAegQIAhAN&biw=1366&bih=626) – JPG Jul 12 '18 at 10:22
0

Simply set a default value for role:

role = models.ForeignKey(
        Role,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        default=Role.objects.get(role='agent'))
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • what if there is no role object with agent. I have to add the role from the admin for this to work i think. Will not it be better, if i check in save method if role object with agent exists or not if not then create one and assign. What is your suggestion on this? – milan Jul 12 '18 at 02:14
  • If you are going to create a `Role` of `'agent'` anyway, you can use `default=Role.objects.get_or_create(role='agent')[0]` instead. – blhsing Jul 12 '18 at 02:34
  • that way I am getting "There are some values Django cannot serialize into migration files." error when doing makemigrations – milan Jul 12 '18 at 03:34