0

I'm trying to add custom functionality to django router methods.

This is my router that exposes the standard methods on an user.

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [BasePermission]

I'm validating the user using serializer validation methods.

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    MOBILE_ERROR = 'Mobile number should be 10 digits long and only contain numbers.'
    EMAIL_ERROR = 'Incorrect email format'
    USERNAME_ERROR = 'Username must be at least 6 characters long and contain only letters and numbers.'

    class Meta:
        model = User
        fields = '__all__'

    def validate_mobile(self, value):
        regexp = re.compile(r'^[0-9]{10}$')
        if regexp.search(value):
            return value
        raise serializers.ValidationError(self.MOBILE_ERROR)

    def validate_email(self, value):
        if validate_email(value):
            return value
        raise serializers.ValidationError(self.EMAIL_ERROR)

    def validate_username(self, value):
        regexp = re.compile(r'^[a-zA-Z0-9]{6,}$')
        if regexp.search(value):
            return value
        raise serializers.ValidationError(self.USERNAME_ERROR)

And this is my route.

router = DefaultRouter(trailing_slash=False)
router.register(r'user', UserViewSet),
urlpatterns = router.urls

I want to add a method send_activation_code if the user is created successfully. How do I do this?

1

1 Answer 1

1

For such purpose you can use signals. Every time when your app creates new User instance - some action should be performed. In your case you should connect build-in signal post_save and your existed send_activation_code function

Example for your case:

yourapp/signals.py:

from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def send_activation_code_signal(sender, instance, created, **kwargs):
    if created:
        send_activation_code(instance.phone_number)

Also, you need to import signals in your app config file

yourapp/app.py:

from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _

class YourAppConfig(AppConfig):
    name = 'yourproject.yourapp'
    verbose_name = _('yourapp')

    def ready(self):
        import yourproject.yourapp.signals

yourapp/__init__.py:

default_app_config = 'yourproject.yourapp.apps.YourAppConfig'

If you dont need to send code every time User instance created - you can specify more statements, for example:

if created and instance.validated:
    send_activation_code(instance.phone_number)

There are some more useful built-in signals in Django, check docs Django signals docs: https://docs.djangoproject.com/en/3.0/ref/signals/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.