Django model stoped working when adding more models - python

I have a view in which the user can edit their profile everything worked fine and everything was being updated (biography, first_name, username, email and profile-picture) but now that I added a new app that contains three views in which the user can upload, delete and like posts, the user update sistem stoped working for some reason just the (update, email, first_name)still worked. The update view calls 2 models, User that lets you edit(name, username and email) and Profile that lets you edit(bio and change the profile pictures) it looks like when I added the upload, delete and like functions mentioned before, the whole Profile model "disapeared" even tho is there. The error I am getting is RelatedObjectDoesNotExist User has no profile.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(upload_to='profile_pics', null=True, blank=True, default='default.png')
bio = models.CharField(max_length=400, default=1, null=True)
connection = models.CharField(max_length = 100, blank=True)
follower = models.IntegerField(default=0)
following = models.IntegerField(default=0)
def __str__(self):
return f'{self.user.username} Profile'
class Post(models.Model):
text = models.CharField(max_length=200)
video = models.FileField(upload_to='clips', null=True, blank=True)
user = models.ForeignKey(User, related_name='imageuser', on_delete=models.CASCADE, default='username')
liked = models.ManyToManyField(User, default=None, blank=True, related_name='liked')
updated = models.DateTimeField(auto_now=True)
created =models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.text)
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike'),
)
class Like(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES, default='Like', max_length=10)
def __str__(self):
return str(self.post)
views.py
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
form1 = UpdateProfileForm(request.POST, request.FILES, instance=request.user.profile)
if form.is_valid and form1.is_valid:
form.save()
form1.save()
return redirect('profile')
else:
form = EditProfileForm(instance=request.user)
form1 = UpdateProfileForm(instance=request.user)
args = {
'form': form,
'form1': form1,
}
return render(request, 'profile-edit.html', args)
urls.py
urlpatterns = [
path('<username>/', views.profile, name='profile'),
path('edit-profile', views.edit_profile, name='edit-profile'),
]
forms.py
class EditProfileForm(UserChangeForm):
class Meta:
model = User
fields = (
'first_name',
'username',
'email',
)
exclude = ('password',)
class UpdateProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = (
'bio',
'profile_pic',
)
If you need to see more code please let me know in the comments.

Add the following in your views before the if statement:
profile, created = Profile.objects.get_or_create(user=request.user)
You need the ", created" since the result of get_or_create will be a tuple not an object - the profile either already exists or must be created.
For your new problem, change the following line:
form1 = UpdateProfileForm(request.POST, request.FILES, instance=request.user.profile)
to:
form1 = UpdateProfileForm(request.POST or None, request.FILES, instance=request.user.profile)

Related

How can I connect a model instance to a user in django?

Im looking to make it so the logged in user that creates a profile is linked to their guestprofile model when they create their profile.
When I create the guest profile while logged in, it successfully creates the guest profile, but in the guest profile admin screen there is no user connected to the guest profile model created. Instead there is a dropdown menu listing all users, which makes the connection process manual. Thanks.
Forms.py
class AddProfileForm(forms.ModelForm):
name = forms.CharField(max_length=50, widget=forms.TextInput(attrs={'class': 'form-control'}))
location = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
summary = forms.CharField(max_length=500, widget=forms.Textarea(attrs={'class': 'form-control'}))
profile_pic = forms.ImageField()
class Meta:
model = GuestProfile
fields = ('name', 'location', 'summary', 'profile_pic')
Models.py
class GuestProfile(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
location = models.CharField(max_length=100)
summary = models.TextField(max_length=350)
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/")
def __str__(self):
return str(self.user)
views.py
class AddProfileView(CreateView):
model = GuestProfile
form_class = AddProfileForm
template_name = 'profilemanip/addprofile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
Edit: I ended up solving my issue by changing my AddProfileView to the following:
def AddProfileView(request,*args,**kwargs):
form = AddProfileForm(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
form = AddProfileForm()
return render(request, "profilemanip/addprofile.html", {"form": form})

How do I connect a model instance to a user in django?

Im looking to make it so the logged in user that creates a profile is linked to their guestprofile model when they create their profile.
When I create the guest profile while logged in, it successfully creates the guest profile, but in the guest profile admin screen there is no user connected to the guest profile model created. Instead there is a dropdown menu listing all users, which makes the connection process manual. Thanks.
Forms.py
class AddProfileForm(forms.ModelForm):
name = forms.CharField(max_length=50, widget=forms.TextInput(attrs={'class': 'form-control'}))
location = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
summary = forms.CharField(max_length=500, widget=forms.Textarea(attrs={'class': 'form-control'}))
profile_pic = forms.ImageField()
class Meta:
model = GuestProfile
fields = ('name', 'location', 'summary', 'profile_pic')
Models.py
class GuestProfile(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
location = models.CharField(max_length=100)
summary = models.TextField(max_length=350)
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/")
def __str__(self):
return str(self.user)
views.py
class AddProfileView(CreateView):
model = GuestProfile
form_class = AddProfileForm
template_name = 'profilemanip/addprofile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
Edit: I ended up solving my issue by changing my AddProfileView to the following:
def AddProfileView(request,*args,**kwargs):
form = AddProfileForm(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
form = AddProfileForm()
return render(request, "profilemanip/addprofile.html", {"form": form})
Try adding this to your AddProfileForm in order to associate the user with the profile:
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user',None)
super(AddProfileForm, self).__init__(*args, **kwargs)

Profile ID not stored in User after creation Django

I wrote the following code:
class RegisterForm(UserCreationForm):
email = forms.EmailField(max_length=200, help_text='Required')
class Meta:
model = CustomUser
fields = ('username', 'email', 'password1', 'password2')
#login_required(login_url="/login")
def index(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
profile = Profile().save()
user = form
user.profile = profile
user.save()
return redirect('users')
else:
print(form.errors)
else:
form = RegisterForm()
user_model = get_user_model()
users = user_model.objects.all()
paginator = Paginator(users, 15)
page = request.GET.get('page')
users = paginator.get_page(page)
return render(request, 'users/index.html', {'users': users, 'form': form})
class Profile(models.Model):
has_premium_until = models.DateTimeField(null=True, blank=True)
has_premium = models.BooleanField(default=False)
has_telegram_premium_until = models.DateTimeField(null=True, blank=True)
has_telegram_premium = models.BooleanField(default=False)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
class CustomUser(AbstractUser):
email = models.EmailField(max_length=255, unique=True)
profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True)
When I'm submitting the form the user as well as the profile is created but the profile is not stored in the user (the profile_id stays null).
Anyone who can help me out?
Change your code to
if form.is_valid():
profile = Profile().save()
user = form.save(commit=False)
user.profile = profile
user.save()
return redirect('users')
This way the user object will be created and then you refer to the profile ju just created and save it.
There is however another way of doing it with signals:
#receiver(models.signals.post_save, sender=CustomUser)
def create_profile_on_user_reg(sender, instance, created,**kwargs):
if created:
instance.profile = Profile()
instance.save()
Check out more on Django signals documentation

Django extra registration details not saving

I have form.py with class RegistrationForm and everything works fine but the extra details like email, first and last name, roles is not saved to my account/User profiles but first and last name + emails is saved under AUTHENTICATION AND AUTHORIZATION/Users
I been trying to figure our if I made some mix up with model, form or views.
What could be the problem? Using python 3 with latest django
2nd
3rd
Models.py
class UserProfile(models.Model):
STUDENT = 1
TOURIST = 2
BUSINESS = 3
ADMIN = 4
ROLE_CHOICES = (
(STUDENT, 'Student'),
(TOURIST, 'Tourist'),
(BUSINESS, 'Business'),
(ADMIN, 'Admin'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
# first_name = models.CharField(max_length=100, default='')
# last_name = models.CharField(max_length=100, default='')
email = models.EmailField()
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='image_profile', blank=True)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
# admin = UserProfileManager()
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
forms.py
ROLES = ((0, 'Student'), (1, 'Tourist'), (2, 'Business'))
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
role = forms.ChoiceField(choices=ROLES)
class Meta:
model = User
fields = (
'username',
'first_name',
'last_name',
'email',
'role',
'password1',
'password2'
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.role = self.cleaned_data['role']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
views.py
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your account has been created!')
return redirect(reverse('city:home'))
else:
form = RegistrationForm()
args = {'form': form}
return render(request, 'account/register_form.html', args)
Admin.py
class UserProfileAdmin(admin.ModelAdmin):
list_display = ('user', 'role', 'email')
def user_info(self, obj):
return obj.role
def get_queryset(self, request):
queryset = super(UserProfileAdmin, self).get_queryset(request)
queryset = queryset.order_by('email')
return queryset
role.short_description = 'User Type'
admin.site.register(UserProfile, UserProfileAdmin)
By given screen shots i think you are using allauth library. If you want to use allauth and modify user model then you have to import AbstractUser class of allauth
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone = models.CharField(_('Telephone'), blank=True, max_length=20)
address = models.CharField(_('Address'), blank=True, max_length=255)

Django auth.models User One-To-Many (1048, "Column 'user_id' cannot be null")

I'm new to django and my task is to make user able to create a lot profiles after registration when he's logged in.
This is my models.py:
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(blank=False, max_length=100)
lastname = models.CharField( blank=False, max_length=100)
city = models.CharField( blank=True, max_length=100)
country = models.CharField( blank=True, max_length=100)
phonenumber = models.CharField(blank=False, null=True, max_length=20)
email = models.EmailField(blank=False, max_length=100)
date_of_birth = models.DateField( blank=True, null=True)
date_of_addition = models.DateField(auto_now=True, editable=False, null=True)
When I create my user, do login and press create profile button I get :
django.db.utils.IntegrityError: (1048, "Column 'user_id' cannot be null")
This is my views.py:
#login_required
def profile_create(request):
data = dict()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
data['form_is_valid'] = True
profiles = Profile.objects.all()
data['html_profile_list'] = render_to_string('basic_app/users_list_1_10.html', {'profiles': profiles})
else:
data['form_is_valid'] = False
else:
form = ProfileForm()
context = {'form': form}
data['html_form'] = render_to_string('basic_app/partial_profile_create.html', context, request=request)
return JsonResponse(data)
def register(request):
registered = False
if request.method == "POST":
user_form = UserForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserForm()
return render(request,'basic_app/registration.html',{'user_form':user_form,'registered':registered})
This is my forms.py:
from django import forms
from django.forms import ModelForm
from django.contrib.auth.models import User
from .models import Profile
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = ('name', 'lastname', 'city', 'country', 'phonenumber', 'email', 'date_of_birth')
class UserForm(ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
username = forms.CharField(help_text=False)
class Meta():
model = User
fields = ('username','password')
Thanks
It happens because in your Profile model you have user field which is ForeignKey. In Django ForeignKey is required by default, which means that you can't create new Profile without specifying user field. But you don't provide user in ProfileForm.
You can either provide user in ProfileForm or set user field as not required by adding:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
I should request user before saving ProfileForm:
#login_required
def profile_create(request):
data = dict()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
add = form.save(commit=False)
add.user = request.user
add.save()
data['form_is_valid'] = True
profiles = Profile.objects.all()
data['html_profile_list'] = render_to_string('basic_app/users_list_1_10.html', {'profiles': profiles})
else:
data['form_is_valid'] = False
else:
form = ProfileForm()
context = {'form': form}
data['html_form'] = render_to_string('basic_app/partial_profile_create.html', context, request=request)
return JsonResponse(data)

Categories

Resources