RelatedObjectDoesNotExist at /profile/ User has no profile - python-3.x

I want to create a profile for each user but I received this error message and this my function in :
views.py :
#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():
user_from =u_form.save()
profile_form= p_form.save(False)
user_from=profile_form
profile_form.save()
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('list')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile) #instance=request.user.profile)
args = {}
args['u_form'] = u_form
args['p_form'] = p_form
return render(request, 'users/profile.html',args)
register user :
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()
return render(request, 'users/register.html', {'form': form})
why this code don't working? I'm trying to create a registration form for users.
models.py :
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,unique=True, primary_key=True, default=None)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self):
super().save()

Related

NOT NULL constraint failed: dashboard_profile.user_id

I'm trying to save the last IP of User to the Profile module in Django but I get always NOT NULL constraint failed I know that last_ip should be set tonull=True and I run this commands:py .\manage.py makemigrations and py .\manage.py migrate. if you have any suggestions to save IP to the user that will be helpful for me.
Thanks in advance.
#models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True, max_length=150)
last_ip = models.GenericIPAddressField(null=True, blank=True)
avatar = ContentTypeRestrictedFileField(max_upload_size=10485760, null=True, verbose_name="",default='default.jpg', blank= True, content_types=['image/png', 'image/jpeg'])
def __str__(self):
return self.user.username
#forms.py
class UpdateUserForm(forms.ModelForm):
username = forms.CharField(max_length=150, required=True)
first_name = forms.CharField(max_length=150, required=False)
last_name = forms.CharField(max_length=150, required=False)
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ['username','first_name','last_name','email']
class UpdateAvatarBio(forms.ModelForm):
avatar = forms.ImageField()
bio = forms.CharField()
class Meta:
model = Profile
fields = ['avatar', 'last_ip', 'bio']
#views.py
def ip_client(request):
return (
x_forwarded_for.split(',')[0]
if (x_forwarded_for := request.META.get('HTTP_X_FORWARDED_FOR'))
else request.META.get('REMOTE_ADDR')
)
def profile(request):
ip = ip_client(request)
model = Profile(last_ip=ip)
model.save() # Traceback suppose here is the issue
if request.method == 'POST':
...
...
return render(request, 'profile.html', {'user_form': user_form, 'profile_form': profile_form})
You didn't add the user to Profile before saving it
def profile(request):
ip = ip_client(request)
model = Profile(last_ip=ip)
moddl.user=request.user #Add this
model.save() # Traceback suppose here is the issue
if request.method == 'POST':
...
...
return render(request, 'profile.html', {'user_form': user_form, 'profile_form': profile_form})
Edit:
Since the user is OneToOne (which means it is a the primary key), so Your code shall be like this
def profile(request):
ip = ip_client(request)
profile = Profile.objects.get(user=request.user)
profile.last_ip = ip
profile.save()
if request.method == 'POST':
...
...
return render(request, 'profile.html', {'user_form': user_form, 'profile_form': profile_form})

How to get a value of foreign key between apps of Django?

If somebody has this kind of issue, answer is below, did it :)
I have two apps (accounts and company).
accounts/models.py
class Organization(models.Model):
organization_name = models.CharField(max_length=20)
#custom user model
class NewUser(AbstractBaseUser):
which_organization = models.ForeignKey(Organization, on_delete = models.CASCADE, null=True, blank=True)
#other fields
company/models.py
from accounts import models as accounts_model
class Branch(models.Model):
branch_name = models.ForeignKey(
accounts_model.Organization, on_delete = models.CASCADE, null=True, blank=True)
#other fields
company/forms.py
from .models import Branch
class BranchForm(forms.ModelForm):
class Meta:
model = Branch
fields = '__all__'
company/views.py
from .forms import BranchForm
def some_function(request):
form = BranchForm()
if request.method == 'POST':
form = BranchForm(request.POST, request.FILES)
if form.is_valid():
form.save(commit=False)
form.branch_name = request.user.which_organization
print("User organization: ", request.user.which_organization)
form.save()
return render(request, 'company/index.html', {'form': form})
P.s. Everything works well. I am able to print the user's organization with
print("User organization : ", request.user.which_organization)
But cannot save it with
form.branch_name = request.user.which_organization
in views.py. Instead of getting exact organization name of the user, created object lists all organization names...
How to achieve it?)
Did it :D
def some_function(request):
form = BranchForm()
if request.method == 'POST':
form = BranchForm(request.POST, request.FILES)
if form.is_valid():
another_form = form.save(commit=False)
another_form.branch_name = Organisation.objects.get(id= request.user.which_organization.id )
new_form.save()
return render(request, 'company/index.html', {'form': form})
Try passing an instance of the Organisation model,
def some_function(request):
form = BranchForm()
if request.method == 'POST':
form = BranchForm(request.POST, request.FILES)
if form.is_valid():
form.save(commit=False)
organisation_instance = Organisation.objects.get(id = request.user.which_organization.id )
form.branch_name = organisation_instance
print("User organization: ", request.user.which_organization)
form.save()
return render(request, 'company/index.html', {'form': form})

Why django is accepting two diiferent passwords? Giving no error at all

Why this code is accepting both password and confirm_password field? without errors
Here is first models.py file: (indent is not a problem here)
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from .managers import UserManager
from django.utils.translation import ugettext_lazy as _
# Create your models here.
ROLES = (
('Customer', 'Customer'), ('Vendor', 'Vendor')
)
class User(AbstractBaseUser):
email = models.EmailField(verbose_name='Email Address', max_length=255, unique=True)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
role = models.CharField(max_length=15, choices=ROLES)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
objects = UserManager()
def __str__(self):
return self.email
def get_name(self):
return self.first_name + ' ' + self.last_name
def get_role(self):
return self.role
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
Next the manager for user model:
Here I'm just accepting data and creating accounts only.
from django.contrib.auth.models import BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
if not email:
raise ValueError('User must have an Email Address')
user = self.model(email=self.normalize_email(email), **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password, **extra_fields):
extra_fields.setdefault('staff', False)
extra_fields.setdefault('admin', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('staff', True)
extra_fields.setdefault('admin', True)
if extra_fields.get('staff') is not True:
raise ValueError('Superuser must have "staff" = True')
if extra_fields.get('admin') is not True:
raise ValueError('Superuser must have "admin" = True')
return self._create_user(email, password, **extra_fields)
In here, I want create model forms for creating user accounts
Here is forms.py file:
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from .models import User
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'role', 'password', 'password2')
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError('Email is already taken, try another email')
return email
def clean_password2(self):
password = self.cleaned_data.get('password')
password2 = self.cleaned_data.get('password2')
if password and password2 and password != password2:
raise forms.ValidationError('Passwords did not match, try again')
return password
class UserAdminCreationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
def clean_password2(self):
password = self.cleaned_data.get('password')
password2 = self.cleaned_data.get('password2')
if password and password2 and password != password2:
raise forms.ValidationError('Passwords did not match, try again')
return password
def save(self, commit=True):
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data['password'])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'role', 'password', 'admin', 'staff')
def clean_password(self):
return self.initial['password']
Lastly here is the views file:
from django.shortcuts import render, redirect
from .models import User
from .forms import RegistrationForm
from django.contrib import messages
from .models import User
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
import logging
logger = logging.getLogger(__name__)
# Create your views here.
def register(request):
form = RegistrationForm()
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
password = form.cleaned_data['password']
role = form.cleaned_data['role']
user = User.objects.create_user(
email=email,
password=password,
first_name=first_name,
last_name=last_name,
role=role,
)
logger.info('New account created by {0} {1} with email:{2} as {3}'.format(
first_name, last_name, email, role
))
messages.success(request, 'Hi, ' + first_name + ', your account is created successfully!')
return redirect('/')
context = {'form': form,}
return render(request, 'user/register.html', context)
def user_login(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect('user:home')
else:
messages.warning(request, 'Email or Password is incorrect, try again')
context = {}
return render(request, 'user/login.html', context)
def user_logout(request):
logout(request)
return redirect('user:login')
#login_required(login_url='user:login')
def home(request):
users = User.objects.all()
context = {'users': users}
return render(request, 'user/home.html', context)
I can not see a password2 field in your registration form. Most probably there is no password2 and according to your code written, "passwords are equal or not" condition will be checked if both passwords are provided. As password2 does not exist, the following "if condition" is always false. Hence validation error is not raised and the password is returned every time.
if password and password2 and password != password2:
raise forms.ValidationError('Passwords did not match, try again')
return password

Getting the post instance in Django class based views

I currently use a function based view to let users write comments on posts, but I'm trying to convert it to class based views
Function views.py
def comment(request, pk):
form = CommentForm(request.POST)
# Post instance
post_instance = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
if form.is_valid:
obj = form.save(commit=False)
obj.commenter = request.user
obj.post = post_instance
obj.save()
return redirect('/')
else:
messages.error(request, 'Comment Failed')
return render(request, 'comment.html', {'form': form})
Class views.py
class CommentView(FormView):
template_name = 'comment.html'
form_class = CommentForm
success_url = '/'
def get_object(self):
pk = self.kwargs.get('pk')
post_instance = get_object_or_404(Post, pk=pk)
return post_instance
def form_valid(self, form):
obj = form.save(commit=False)
obj.commenter = self.request.user
obj.post = post_instance
obj.save()
return super().form_valid(form)
I'm trying to implement the same logic for saving the comment but I get the error: name 'post_instance' is not defined
get_object() is returning the 'post_instance' variable but I can't access it.
Could you guys show me where I'm doing a mistake, thanks in advance!
You can try:
class CommentView(FormView):
template_name = 'comment.html'
form_class = CommentForm
success_url = '/'
def get_object(self):
pk = self.kwargs.get('pk')
post_instance = get_object_or_404(Post, pk=pk)
return post_instance
def form_valid(self, form):
obj = form.save(commit=False)
obj.commenter = self.request.user
obj.post = self.get_object()
obj.save()
return super().form_valid(form)

Cannot submit the form with foreign key in Django

I can't submit the form with foreign key. Is it anything with foreign key?
I always redirect to the destination_list since the form is not saving.
No error is showing.
models.py
class Region(models.Model):
region = models.CharField("Region",max_length=45,blank=True)
status = models.CharField("Status",max_length=45,blank=True)
selected_region = models.CharField("Selected Region",max_length=45,blank=True)
def __str__(self):
return self.region
def get_absolute_url(self):
return reverse('update2', args=[str(self.id)])
def get_delete_url(self):
return reverse('delete2', args=[str(self.id)])
class Destination(models.Model):
region1 = models.ForeignKey(Region)
destination = models.CharField("destination",max_length=30,blank=False,unique=True)
status = models.CharField("status",max_length=30,blank=False,unique=True)
selected_destination = models.CharField("select destination",max_length=30)
def __str__(self):
return self.destination
forms.py
class DestinationForm(forms.ModelForm):
class Meta:
model = Destination
fields = [ 'region1','destination','status','selected_destination']
def __init__(self, *args, **kwargs):
super(DestinationForm, self).__init__(*args, **kwargs)
for key in self.fields:
self.fields[key].widget.attrs['class'] = 'form-control'
views.py
(I have redirect to destination_list if form is not submitted)
def add_destination(request):
form = DestinationForm()
context = {
"form": form
}
if request.method == 'POST':
form = DestinationForm(request.POST)
if form.is_valid():
form.save()
else:
return redirect(destination_list)
return render(request,'adddestination.html',context)

Resources