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