Creating profile & add group with signals

Well, My Django Administration has the Group customer and staff, but I cant add user with group customer using signal.

models.py

class Customer(models.Model):
    user = models.OneToOneField(User, blank= True , null= True, on_delete=models.CASCADE)
    name = models.CharField(max_length=255, null=True)
    phone = models.CharField(max_length=255, null=True)
    email = models.CharField(max_length=255, null=True)
    profile_pic = models.ImageField(default="user01.png", null=True, blank=True) # pip install pillow
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    def __str__(self):
        return self.name

urls.py

urlpatterns = [
    path('register/', views.registerPage, name='register'),
    path('login/', views.loginPage, name='login'),
    path('logout/', views.logoutUser, name='logout'),
    
    path('', views.home, name='home'),
    path('user_page/', views.userPage, name='user_page'),
    
    path('account/', views.accountSettings, name='account'),
    
    path('products/', views.products, name='products'),
    path('customer/<str:pk>/', views.customer, name='customer'),
    
    path('create_order/<str:pk>/', views.createOrder, name='create_order'),
    path('update_order/<str:pk>/', views.updateOrder, name='update_order'),
    path('delete_order/<str:pk>/', views.deleteOrder, name='delete_order'),
]

views.py

@unauthenticated_user
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 was created for ' + username)   
            
            return redirect('login')
    
    context = {'form':form}
    return render(request, 'accounts/register.html', context)

signals.py

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

# create your models here 	


def customer_profile(sender, instance, created, **kwargs):
    if created:
        group = Group.objects.get(name='customer')
        instance.groups.add(group)
        
        Customer.objects.create(
           user=instance,
           name=instance.username,
           email=instance.email, 
        )
       
        print('Profile CREATED!')

post_save.connect(customer_profile, sender=User)

settings.py
INSTALLED_APPS = [
ā€˜django.contrib.adminā€™,
ā€˜django.contrib.authā€™,
ā€˜django.contrib.contenttypesā€™,
ā€˜django.contrib.sessionsā€™,
ā€˜django.contrib.messagesā€™,
ā€˜django.contrib.staticfilesā€™,

'accounts.apps.AccountsConfig',
# 'accounts',
'django_filters',

]

apps.py

from django.apps import AppConfig

class AccountsConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'accounts'

def ready(self):
    import accounts.signals

So, user is created and customer within group costumer not
Seems signal was not called and there isnā€™t print on terninal from print(ā€˜Profile CREATED!ā€™)

Are you getting any traceback error messages on the console?

Do you have a group with name ā€œcustomerā€?

What model is your registerPage view creating an instance of?

You might want to put a print statement directly below the def customer_profile line and above the if statement to verify that the signal is being received by that function.

Are you getting any traceback error messages on the console?
A- no, just when I login I got

[13/Apr/2023 17:49:09] "GET /register/ HTTP/1.1" 302 0
Internal Server Error: /
Traceback (most recent call last):
  File "C:\Users\HP\Desktop\projetoWeb\User Registration and Login Authentication\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\HP\Desktop\projetoWeb\User Registration and Login Authentication\venv\Lib\site-packages\django\core\handlers\base.py", line 204, in _get_response
    self.check_response(response, callback)
  File "C:\Users\HP\Desktop\projetoWeb\User Registration and Login Authentication\venv\Lib\site-packages\django\core\handlers\base.py", line 332, in check_response
    raise ValueError(
ValueError: The view accounts.decorators.wrapper_func didn't return an HttpResponse object. It returned None instead.[13/Apr/2023 17:49:09] "GET / HTTP/1.1" 500 67424

Do you have a group with name ā€œcustomerā€? just after do login because the user must be in the custumer group
A- Yes, I do with django administration

What model is your registerPage view creating an instance of?
An instance of user

You might want to put a print statement directly below the def customer_profile line and above the if statement to verify that the signal is being received by that function.
A- I put this way but I didnā€™t get messages from terminal.

I got this system there Creating Customer Profiles with Django Signals | Django (3.0) Crash Course Tutorials (pt 19) - YouTube
Iā€™m stucked in this issue on video 19 ( just 7 min)

This is a traceback. So yes, you are getting a traceback error message.

This is occurring after the

redirect has been received.

This means that the issue here is with the view that you are redirecting to.

Youā€™re getting the 500 error here:

What is the view that handles the ā€œblankā€ url?

Thankyou so much, I must stop my head was boling

the view for the error is login:

@unauthenticated_user
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 was created for ' + username)
           
           
            
            return redirect('login')
    
    context = {'form':form}
    return render(request, 'accounts/register.html', context)

login

@unauthenticated_user
def loginPage(request):
    
    
    
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        
        
        user = authenticate(request, username=username, password=password )
        
        if user is not None:
            login(request, user)
            return redirect('home')
        else:
            messages.info(request, 'username or password is incorrect!')
                    
    context = {}
    return render(request, 'accounts/login.html', context)

Your urls.py file shows that the empty url is defined as:

What is your home view? That is where the problem is occurring.

hi, sir.

Register page must register an user and add it to a customer group.

When I create a user and add it manually in Django Administration to customer group, the system works. fine after login.

Thank you in advance

Right at the moment, Iā€™m trying to address the cause of the traceback error you posted earlier.

To address that, I need to see your home view.

1 Like
@login_required(login_url='login')
@admin_only
def home(request):    
    orders = Order.objects.all()
    customers = Customer.objects.all()
    
    total_customers = customers.count()
    
    total_orders = orders.count()
    delivered = orders.filter(status='Delivered').count()
    pending = orders.filter(status='Pending').count()
    
    context = {'orders':orders, 'customers':customers,
        'total_orders':total_orders,'delivered':delivered, 'pending':pending          
              }
    return render(request,'accounts/dashboard.html', context)

Thatā€™s the content of home for customers

{% extends 'accounts/main.html' %}
 

    {% block content %} 

    {% include 'accounts/status.html' %} 
    <br>  
    <div class="row">
        <div class="col-md-5">
            <h5>CUSTOMERS</h5>
            <br>
            <div class="card card-body">
                <a class="btn btn-primary btn-sm btn-block" href="">
                    Create Customer
                </a>
                <table class="table table-sm">
                    <tr>
                        <th></th>
                        <th>Customers</th>
                        <th>Phone</th>                        
                    </tr> 
                    {% for customer in customers  %}
                        <tr>
                            <td> <a href="{% url 'customer' customer.id %}" class="btn btn-sm btn-success">view</a> </td>
                            <td>{{ customer.name }}</td>
                            <td>{{ customer.phone }}</td>
                        </tr>
                    {% endfor %}
                </table>
            </div>
        </div> 
        
        <div class="col-md-7">
            <h5>LAST 5 ORDERS</h5>
            <br>
            <div class="card card-body">                
                <table class="table table-sm">
                    <tr>
                        <th>Product</th>
                        <th>Date Ordered</th>
                        <th>Status</th>
                        <th>Update</th>
                        <th>Remove</th>                        
                    </tr> 
                    {% for order in orders  %}
                    <tr>
                        <td>{{ order.product }}</td>
                        <td>{{ order.date_created }}</td>
                        <td>{{ order.status }}</td>
                        <td><a href="{% url 'update_order' order.id %}" class="btn btn-sm btn-warning">Update</a></td>
                        <td><a href="{% url 'delete_order' order.id %}" class="btn btn-sm btn-danger">Delete</a></td>
                        
                        
                    </tr>
                {% endfor %}
                </table>
            </div>
        </div>

    </div>
    
    {% endblock content %}

Is this a decoration you have written or a third-party? I donā€™t see it as being a Django-provided decorator.

If it is a third-party decorator, please tell me what package provides it. If itā€™s one youā€™ve written, please post it here.

I think itā€™s from decorators by importing

from .decorators import unauthenticated_user, allowed_users, admin_only

that is the groups created in Django administration

decorators.py

from django.http import HttpResponse
from django.shortcuts import redirect

def unauthenticated_user(view_func):
    def wrapper_func(request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect('home')
        else:
            return view_func(request, *args, **kwargs)
    
    return wrapper_func

def allowed_users(allowed_roles=[]):
    def decorator(view_func):
        def wrapper_func(request, *args, **kwargs):
            
            group = None
            if request.user.groups.exists():
                group = request.user.groups.all()[0].name
            
            if group in allowed_roles:                
                # print('Working: ', allowed_roles)
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse('You are not authorized to view this page')
        return wrapper_func
    return decorator


def admin_only(view_func):
    def wrapper_func(request, *args, **kwargs):
        group = None
        if request.user.groups.exists():
            group = request.user.groups.all()[0].name 
        
        if group == 'customer':
            return redirect('user_page')
        
        if group == 'admin':
            return view_func(request, *args, **kwargs)
    
    return wrapper_func

You have an issue here:

Youā€™re not returning an HttpResponse object from this decorator if this condition is true. (The second condition returns the result of a redirect function and the third condition returns the result of the view function.)

thnak you so much for your attention.
Iā€™ll check that

Hi sir, Thank you so much for your help.

Iā€™ve done a stupid thing in apps.py

class AccountsConfig(AppConfig):
    # default_auto_field = 'django.db.models.BigAutoField'
    name = 'accounts'
def ready(self):
      import accounts.signals

identation for function ready:

class AccountsConfig(AppConfig):
    # default_auto_field = 'django.db.models.BigAutoField'
    name = 'accounts'
    def ready(self):
        import accounts.signals