Melissa Stewart
Melissa Stewart

Reputation: 3605

Adding custom functionality to django router methods

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?

Upvotes: 0

Views: 49

Answers (1)

vadimb
vadimb

Reputation: 462

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/

Upvotes: 1

Related Questions