Search code examples
djangotypeerrordjango-signals

Django: TypeError: 'ModelSignal' object is not callable


I have a piece of code throwing an error: TypeError: 'ModelSignal' object is not callable.

While I'm gonna add signals in my project, this error is occuring. Why this type of error is occured? What you need to know to give my answer?

Please help me someone. I'm a newbie to Django. Thanks in advance.

Here is my views.py file:

def registerPage(request):
    form = CreateUserForm()
    if request.method == "POST":
        form = CreateUserForm(request.POST)
        if form.is_valid():
            user =form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, 'Account successfully created for ' + username)

            return redirect ('login')

    context = {'form': form}
    return render(request, 'accounts/register.html', context)

My models.py file:

from django.db import models
from django.contrib.auth.models import User

class Student(models.Model):
    user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=200)
    phone = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)
    profile_pic = models.ImageField(default= 'default-picture.jpg', null= True, blank= True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)

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

My signals.py file:

from django.db.models.signals import post_save
from django.contrib.auth.models import Group, User
from .models import Student

def student_profile(sender, instance, created, **kwargs):
    if created:
        group = Group.objects.get(name = 'Student')
        instance.groups.add(group)
        Student.objects.create(
            user = instance,
            name = instance.username
        )
post_save(student_profile, sender= User)

My apps.py file:

from django.apps import AppConfig


class AccountsConfig(AppConfig):
    name = 'accounts'

    def ready(self):
        import accounts.signals

And my settings.py file:

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '1dcgsc@63l$2w_%+90xqra@z=&(q!8sdxf*dg7k6=ptxi&k8o*'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'accounts.apps.AccountsConfig',
    'django_filters',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'cmp.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'cmp.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Dhaka'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'
MEDIA_URL = '/images/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images')

Solution

  • You are calling the post_save object which is not callable. Try post_save.connect().

    from django.db.models.signals import post_save
    from django.contrib.auth.models import Group, User
    from .models import Student
    
    def student_profile(sender, instance, created, **kwargs):
        if created:
            group = Group.objects.get(name = 'Student')
            instance.groups.add(group)
            Student.objects.create(
                user = instance,
                name = instance.username
            )
    post_save.connect(student_profile, sender= User)
    

    Or you can also try using receiver decorator:

    from django.db.models.signals import post_save
    from django.contrib.auth.models import Group, User
    from django.dispatch import receiver
    from .models import Student
    
    @receiver(post_save, sender=User)
    def student_profile(sender, instance, created, **kwargs):
        if created:
            group = Group.objects.get(name = 'Student')
            instance.groups.add(group)
            Student.objects.create(
                user = instance,
                name = instance.username
            ).save()