Я здесь новенький, привет. Создание моего первого приложения Django пока шло отлично. Теперь у меня есть небольшая проблема, которую я не могу решить самостоятельно.
Когда я пытаюсь создать нового пользователя, связанный профиль не создается.
RelatedObjectDoesNotExist at /login/
User has no profile.
Request Method: POST
Request URL: http://127.0.0.1:8000/login/
Django Version: 3.0.7
Exception Type: RelatedObjectDoesNotExist
Exception Value:
User has no profile.
Exception Location: /Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py in __get__, line 420
На самом деле признателен за вашу помощь.
вывод
[02/Aug/2020 02:20:14] "GET / HTTP/1.1" 200 5034
[02/Aug/2020 02:20:14] "GET /static/list/main.css HTTP/1.1" 304 0
[02/Aug/2020 02:20:16] "GET /register/ HTTP/1.1" 200 6400
[02/Aug/2020 02:20:33] "POST /register/ HTTP/1.1" 200 6571
[02/Aug/2020 02:20:43] "POST /register/ HTTP/1.1" 302 0
[02/Aug/2020 02:20:43] "GET /login/ HTTP/1.1" 200 5944
Internal Server Error: /login/
Traceback (most recent call last):
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/dmszanowski/PycharmProjects/django_to_dos/django_project/users/views.py", line 30, in login_view
login(request, user)
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 131, in login
user_logged_in.send(sender=user.__class__, request=request, user=user)
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 173, in send
return [
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 174, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/Users/dmszanowski/PycharmProjects/django_to_dos/django_project/users/signals.py", line 21, in got_online
user.profile.is_online = True
File "/Users/dmszanowski/PycharmProjects/django_to_dos/venv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 420, in __get__
raise self.RelatedObjectDoesNotExist(
django.contrib.auth.models.User.profile.RelatedObjectDoesNotExist: User has no profile.
[02/Aug/2020 02:21:17] "POST /login/ HTTP/1.1" 500 90315
apps.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
forms.py
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, ButtonHolder, Submit
class UserRegisterForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset('Register', 'username', 'email', 'password1', 'password2', css_class='text-white'),
ButtonHolder(Submit('submit', 'Submit', css_class='btn-dark mb-3')))
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
models.py
from django.contrib.auth.models import User
from django.db import models
import os
from PIL import Image
from .validators import validate_image_file_extension
from .storage import OverwriteFile
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
is_private = models.BooleanField(default=0)
is_online = models.BooleanField(default=0)
image = models.ImageField(default='profile_pics/default.jpg', upload_to='profile_pics', blank=True, storage=OverwriteFile(), validators=[validate_image_file_extension])
def __str__(self):
return f'{self.user.username}'
def save(self, *args, **kwargs):
# image_path = os.path.join('profile_pics/', self.image.path)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img = img.convert('RGB')
if 'default.jpg' not in self.image.name:
os.remove(self.image.path)
self.image.name = 'profile_pics/' + str(self.user_id) + "." + self.image.name.split(".", 2)[1]
img.save(self.image.path, "JPEG")
signal.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
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()
storage.py
from django.core.files.storage import FileSystemStorage
from django.conf import settings
import os
class OverwriteFile(FileSystemStorage):
def get_available_name(self, name, max_length=None):
if self.exists(name):
os.remove(os.path.join(settings.MEDIA_ROOT, name))
return name
views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm
from .models import User, Profile
def register_view(request):
if request.method == 'POST':
user_register_form = UserRegisterForm(request.POST)
if user_register_form.is_valid():
user = user_register_form.save()
Profile.objects.create(**{'user': user})
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
user_register_form = UserRegisterForm()
return render(request, 'users/register.html', {'user_register_form': user_register_form})
validators.py
import os
from django.core.exceptions import ValidationError
def validate_image_file_extension(value):
ext = os.path.splitext(value.name)[1]
valid_ext = ['.png', '.jpg', '.jpeg']
if not ext.lower() in valid_ext:
raise ValidationError('Unsupported image file extension. Allowed vales %(value)s', params={'value': valid_ext})
settings.py
INSTALLED_APPS = [
'users.apps.UsersConfig',
'list.apps.ListConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms',
]
STATICFILES_DIRS = (
os.path.join('static'),
)
STATIC_URL = '/static/'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
LOGIN_REDIRECT_URL = ''
LOGIN_URL = 'login'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'