I’ve read some other answers for this (almost) question but they didn’t help. I have the following 2 files mixed for user and profile apps(?). In other answers they said this happens if you don’t use >objects.get_or_create or not making signals.py file you’ll get this error but I’ve gone through both of those ways and no results. This is the traceback I get:
Environment: Request Method: GET Request URL: http://127.0.0.1:3000/profile/ Django Version: 3.0.3 Python Version: 3.7.3 Installed Applications: ['blog', 'users', 'crispy_forms', 'django_cleanup', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles'] Installed 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'] Traceback (most recent call last): File "/home/wss/Desktop/projects/python/django/mahour_sanat/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) File "/home/wss/Desktop/projects/python/django/mahour_sanat/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response response = self.process_exception_by_middleware(e, request) File "/home/wss/Desktop/projects/python/django/mahour_sanat/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/wss/Desktop/projects/python/django/mahour_sanat/.venv/lib/python3.7/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view return view_func(request, *args, **kwargs) File "/home/wss/Desktop/projects/python/django/mahour_sanat/mahoursanat/users/views.py", line 38, in profile p_form = ProfileUpdateForm(instance=request.user.profile) File "/home/wss/Desktop/projects/python/django/mahour_sanat/.venv/lib/python3.7/site-packages/django/utils/functional.py", line 225, in inner return func(self._wrapped, *args) File "/home/wss/Desktop/projects/python/django/mahour_sanat/.venv/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 423, in __get__ self.related.get_accessor_name() Exception Type: RelatedObjectDoesNotExist at /profile/ Exception Value: User has no profile.
forms.py:
from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm from .models import Profile class UserRegisterForm(UserCreationForm): email = forms.EmailField() class Meta: model = User fields = ['username', 'email', 'password1', 'password2'] class UserUpdateForm(forms.ModelForm): email = forms.EmailField() class Meta: model = User fields = ['username', 'email'] class ProfileUpdateForm(forms.ModelForm): class Meta: model = Profile fields = ['image']
signal.py:
from django.db.models.signals import post_save from django.contrib.auth.models import User from django.dispatch import receiver from .models import Profile @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_profile(sender, instance, **kwargs): instance.profile.save()
models.py for profile model:
from django.db import models from django.contrib.auth.models import User from PIL import Image class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) image = models.ImageField(default='default.jpg', upload_to='profile_pics') def __str__(self): return f'{self.user.username} Profile' def save(self): super().save() img = Image.open(self.image.path) if img.height > 300 or img.width > 300: output_size = (300, 300) img.thumbnail(output_size) img.save(self.image.path)
and this is the views.py file:
from django.shortcuts import render, redirect from django.contrib import messages from django.contrib.auth.decorators import login_required from .forms import UserRegisterForm, ProfileUpdateForm, UserUpdateForm def register(request): if request.method == 'POST': form = UserRegisterForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') messages.success( request, f'Your account has been created! You are now able to log in') return redirect('login') else: form = UserRegisterForm() context = { 'form': form } return render(request, 'users/register.html', context) @login_required def profile(request): if request.method == 'POST': u_form = UserUpdateForm(request.POST, instance=request.user) p_form = ProfileUpdateForm( request.POST, request.FILES, instance=request.user.profile) if u_form.is_valid() and p_form.is_valid(): u_form.save() p_form.save() messages.success(request, f'Your account has been updated!') return redirect('profile') else: u_form = UserUpdateForm(instance=request.user) p_form = ProfileUpdateForm(instance=request.user.profile) context = { 'u_form': u_form, 'p_form': p_form } return render(request, 'users/profile.html', context)
Thanks for reading this :).
P.S. As I see in admin page, no profiles are made after registration (neither from site nor admin page).
Advertisement
Answer
Good to see someone who’s practicing Django with Corey’s tutorial! It took me few days to catch what went wrong. Here’s how I did it.
Your views.py
looks like this:
@login_required() def profile(request): if request.method == 'POST': u_form = UserUpdateForm(request.POST, instance=request.user) p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
Add one in views.py
so that it looks like below
@login_required() def profile(request): Profile.objects.get_or_create(user=request.user) if request.method == 'POST': u_form = UserUpdateForm(request.POST, instance=request.user) p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
If you happen to face same issue somehow, create a new account and go to profile page and see if it throws any error.