I am trying to create a Register Form but I couldn't find any solution "ModelForm has no model class specified." for this error. I didn't use ModelForm but I take this error. Can somebody explain me why am I taking this error and how can I fix it
// views.py//
from django.shortcuts import render
from .forms import RegisterForm
from django.contrib import messages
from django.contrib.auth import login as dj_login
def register(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
user = {
"username": form.cleaned_data["username"],
"email": form.cleaned_data["email"],
"phone": form.cleaned_data["phone"],
"password1": form.cleaned_data["password1"],
"password2": form.cleaned_data["password2"]
}
user = form.save()
dj_login(request,user)
messages.success(request,"You have completed registration successfully.")
return render(request,"index.html",{"user":user})
else:
messages.info(request,"You couldn't complete registrations!")
else:
form = RegisterForm()
return render(request,"register.html",{"form":form})
// forms.py //
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):
email = forms.EmailField(required=True)
phone = forms.IntegerField(required=True)
class Meta():
user = User
fields = ["username","email","phone","password1","password2"]
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
user.phone = self.cleaned_data["phone"]
if commit:
user.save()
return user
Related
I am creating a donation app that allows donors to create listings. This data is stored in a Django Model and is going to be displayed on a page. I want to save the user's username to the Django model and display it on the page. My code is down below
Models.py
class Donation(models.Model):
title = models.CharField(max_length=30)
phonenumber = models.CharField(max_length=12)
category = models.CharField(max_length=20)
image = models.CharField(max_length=1000000)
deliveryorpickup = models.CharField(max_length=8)
description = models.TextField()
Views.py
from django.contrib.auth.models import User
from django.http.request import RAISE_ERROR
from django.http.response import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.forms import forms, inlineformset_factory
from django.contrib.auth.forms import UserCreationForm, UsernameField
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from home.models import Donation
# Create your views here.
def index(request,*args, **kwargs):
return render(request, "index.html", {} )
#login_required(login_url='/login/')
def dashboard(request,*args, **kwargs):
return render(request, "dashboard.html", {} )
def register(request, ):
if request.user.is_authenticated:
return redirect('/dashboard/')
else:
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been successfully created, {username} ')
return redirect('loginpage')
context = {'form': form}
return render(request, "register.html", context )
def loginpage(request):
if request.user.is_authenticated:
return redirect('/dashboard/')
else:
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('/dashboard')
else:
messages.error(request, 'Username OR password is incorrect')
context = {}
return render(request, 'login.html', context)
def logoutuser(request):
logout(request)
return HttpResponseRedirect('/login/')
#login_required(login_url='/login/')
def donate(request):
if request.method == "POST":
title = request.POST['donationtitle']
phonenumber = request.POST['phonenumber']
category = request.POST['category']
image = request.POST['imagelink']
deliveryorpickup = request.POST['deliveryorpickup']
description = request.POST['description']
ins = Donation(title = title, phonenumber = phonenumber, category = category, image = image, deliveryorpickup = deliveryorpickup, description = description )
ins.save()
return render(request,'donate.html')
Forms.py (This is where the user is created)
class CreateUserForm(UserCreationForm):
username = forms.CharField(required=True, max_length=30, )
email = forms.EmailField(required=True)
first_name = forms.CharField(required=True, max_length=50)
last_name = forms.CharField(required=True, max_length=50)
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2',]
#function to display errors
def clean(self):
cleaned_data=super().clean()
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if User.objects.filter(username=cleaned_data["username"]).exists():
raise ValidationError("This username is taken, please try another one")
elif password1 != password2:
raise forms.ValidationError("2 password fields do not match")
elif len(password1) < 8 or len(password2) < 8:
raise forms.ValidationError("Passwords must be at least 8 characters long")
To associate the user with the Donation model, you should first add a ForeignKey field to the model class:
from django.conf import settings
class Donation(models.Model):
... # your other donation fields
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
blank=True,
null=True,
)
Once you've made this change, and run the migrations, in your views.py you'll pass the currently signed in user to the Donation model creation:
#login_required(login_url='/login/')
def donate(request):
if request.method == "POST":
ins = Donation(
title=request.POST["title"],
... # all of the other fields
user=request.user, # 👈 This adds the user
)
ins.save()
return render(request,'donate.html')
Notes
Using settings.AUTH_USER_MODEL allows your class to use a custom user model, or django's default user model, based on your project's settings.
To understand what on_delete=models.CASCADE does, you should read django's documentation about it.
Also, instead of manually passing all of the request.POST[...] values to the Donation model, I recommend that you use a ModelForm. It will handle errors and validation for you, as well as generate the HTML displayed in the template. Using a model form here would make your view code change to this:
from django.forms import ModelForm
class DonationForm(ModelForm):
class Meta:
model = Donation
exclude = ["user"]
#login_required(login_url="/login/")
def donate(request):
if request.method == "POST":
form = DonationForm(request.POST)
if form.is_valid():
donation = form.save(commit=False)
donation.user = request.user
donation.save()
# Use a redirect to prevent duplicate submissions
# https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#redirect
return redirect(request, ...)
else:
form = DonationForm()
return render(request, "donate.html", {"form": form})
Profile creation for every new user was working properly. But when I resize the image quality of the user profile from my 'models.py' file, then whenever I create a new user it doesn't create profile for that new user. How do I solve this problem? My codes are given below:
Views.py:
from django.shortcuts import render, redirect
from .forms import UserSignupForm, UserUpdateForm, ProfileUpdateForm
from django.contrib import messages
from django.contrib.auth.decorators import login_required
def signup(request):
if request.method == 'POST':
form = UserSignupForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
form.save()
messages.success(request, f'Signup for {username} is successful')
return redirect('login')
else:
form = UserSignupForm()
return render(request, 'users/signup.html', {'title': 'signup', 'form': form})
#login_required
def profile(request):
context = {
'title' : 'Profile'
}
return render(request, 'users/profile.html', context)
#login_required
def update_profile(request):
if request.method == 'POST':
user_update = UserUpdateForm(request.POST, instance=request.user)
profile_update = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if user_update.is_valid() and profile_update.is_valid():
user_update.save()
profile_update.save()
messages.success(request, 'Profile has been updated!')
return redirect('profile')
else:
user_update = UserUpdateForm(instance=request.user)
profile_update = ProfileUpdateForm(instance=request.user.profile)
context = {
'title' : 'Update Information',
'u_form' : user_update,
'p_form' : profile_update
}
return render(request, 'users/profile_update.html', context)
signals.py:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from .models import Profile
from django.dispatch import receiver
#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()
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 UserSignupForm(UserCreationForm):
first_name = forms.CharField(label='Full Name', max_length=150)
email = forms.EmailField()
class Meta:
model = User
fields = ['first_name', 'username', 'email', 'password1', 'password2']
class UserUpdateForm(forms.ModelForm):
first_name = forms.CharField(label='Full Name', max_length=150)
email = forms.EmailField()
class Meta:
model = User
fields = ['first_name', 'username', 'email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
and
models.py
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_pic')
def __str__(self):
return f'{self.user}\'s Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
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)
I got the solution. I don't know it is the right way or not but it's working for me. So the solution is I just change the default image extension from '.jpg' to '.png' in the profile model class and the default picture image extension.
Maybe the PIL library doesn't support the '.jpg. format.
how can I put condition if an email doesn't exist don't send this email to my own email
I'm trying that here when I put (exists) method but I see as if it doesn't work.
in both cases, shows me an email successful message
how can I stops that ?
if there is a mistake in my code becomes error I wish to get advice to process that
sorry, I'm not fluent in English
views.py
from .forms import SignUp, ResetPassword, EditForm
from website import settings
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import PasswordResetView, PasswordResetDoneView
from django.views.generic.edit import FormView
from django.urls import reverse_lazy
from django.core.mail import send_mail
from django.contrib.auth.models import User
class PasswordReset(PasswordResetView, FormView):
template_name = 'account/password_reset_view.html'
success_url = reverse_lazy('account:password_reset_done')
email_template_name = 'account/reset_password_email.html'
subject_template_name = 'account/password_reset_subject.txt'
form_class = ResetPassword
class PasswordResetDone(PasswordResetDoneView):
template_name = 'account/password_reset_done.html'
# Reset Your Password By G-mail Account
def send_mail(self, request, **kwargs):
subject = "Complete the modification of the password form"
message = "please check here"
if request.method == "POST":
user = User.objects.filter(email=str(request.POST['email']))
if user.exists():
recipient = str(request.POST.get(kwargs['Email']))
if subject and message and recipient:
send_mail(subject=subject,
message=message,
from_email=settings.EMAIL_HOST,
auth_user=request.user.email,
auth_password=request.user.password,
recipient_list=[recipient],
fail_silently=False)
return render(request, self.template_name)
else:
return redirect('account:password-reset')
def register(request):
template_name = 'account/register.html'
if request.method == 'POST':
form = SignUp(request.POST)
if form.is_valid():
# save in database
form.save()
return redirect('account:login')
return render(request, template_name, {'form': form})
else:
form = SignUp()
return render(request, template_name, {'form': form})
#login_required
def view_profile(request):
return render(request, 'account/profile.html', {'user': request.user})
#login_required
def edit_profile(request):
template_name = 'account/edit_profile.html'
if request.method == "POST":
form = EditForm(request.POST)
if form.is_valid():
form.save()
return redirect('account:view_profile')
return render(request, template_name, {'form': form})
else:
form = EditForm()
return render(request, template_name, {'form': form})
forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordResetForm
from django import forms
from django.contrib.auth.models import User
class SignUp(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'password1', 'password2', 'email')
def save(self, commit=True):
user = super(SignUp, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
user.set_password(self.cleaned_data['password1'])
# Save this session without saving in database
if commit:
user.save()
return user
class ResetPassword(PasswordResetForm):
email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Type Email'}))
class Meta:
model = User
fields = ('email',)
class EditForm(UserChangeForm):
password = None
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
def edit(self, fields):
user = super(EditForm, self).save(commit=False)
if user.commit:
user.save()
return user
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# sending an email
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'medoabdin#gmail.com'
EMAIL_HOST_PASSWORD = 'medo_rko96'
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
overview = models.TextField(editable=True, help_text="This field is important to make the viewers know you and your experience")
city = models.CharField(max_length=20)
phone = models.IntegerField(default=0)
logo = models.ImageField()
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(receiver=create_profile, sender=User)
the format of the database as following
user Use try catch in your method send_mail and change filter with get such as below line
user = User.objects.get(email=str(request.POST['email']))
Get method will try to find the user if not found in the DB then it will raise user.DoesNotExist exception you can catch it and do whatever you want.
Like :-
def send_mail(self, request, **kwargs):
subject = "Complete the modification of the password form"
message = "please check here"
if request.method == "POST":
try:
user = User.objects.get(email=str(request.POST['email']))
recipient = str(request.POST.get(kwargs['Email']))
if user.is_active and subject and message and recipient:
send_mail(subject=subject,
message=message,
from_email=settings.EMAIL_HOST,
auth_user=request.user.email,
auth_password=request.user.password,
recipient_list=[recipient],
fail_silently=False)
return render(request, self.template_name)
except user.DoesNotExist:
return redirect('account:password-reset')
this is the forms page
from django import forms
from django.contrib.auth.models import User
from .models import Profile
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput, required=False)
class Meta():
model = User
fields = ['username', 'email', 'password']
class ProfileForm(forms.ModelForm):
class Meta():
model = Profile
fields = ['pic']
& this is the views page
from django.shortcuts import render
from .forms import UserForm, ProfileForm
def register(request):
if(request.method == 'POST'):
userform = UserForm(request.POST)
profileform = ProfileForm(request.POST)
if(userform.is_valid() and profileform.is_valid()):
user = userform.save()
user.set_password(user.password)
user.save()
profile = profileform.save(commit=False)
profile.user = user
if('pic' in request.FILES):
profile.pic = request.FILES['pic']
profile.save()
else:
print(userform.errors, profileform.errors)
else:
userform = UserForm()
profileform = ProfileForm()
return render(request, 'register.html', {'userform':userform,
'profileform':profileform})
when I submit the password or the picture it doesn't save the user to the admin area and says that password is required and the picture is not uploaded
You should use commit=False when saving password from the form and not like in ordinary form with using set().
from django import forms
from django.contrib.auth.models import User
from .models import Profile
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput, required=False)
class Meta:
model = Users
fields =['email', 'password', 'username']
class ProfileForm(forms.ModelForm):
class Meta():
model = Profile
fields = ['pic']
from django.shortcuts import render
from .forms import UserForm, ProfileForm
def register(request):
if(request.method == 'POST'):
form = UserForm(request.POST or None)
profileform = ProfileForm(request.POST or None)
if(userform.is_valid() and profileform.is_valid()):
userform = form.save(commit=False)
userform.password = make_password(form.cleaned_data['password'])
userform.save()
profile = profileform.save(commit=False)
profile.user = user
if('pic' in request.FILES):
profile.pic = request.FILES['pic']
profile.save()
else:
print(userform.errors, profileform.errors)
else:
userform = UserForm()
profileform = ProfileForm()
return render(request, 'register.html', {'userform':userform,
'profileform':profileform})
Look at this link also.
I´m working with Django Framework and it throws this exception: ModelForm has no model class specified.
This is my code:
views.py
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import redirect
from DjangoApp1.forms import login_form
from django.shortcuts import render #For render templates
def login_view(request):
form = login_form()
context = { 'form': form, 'mensaje':'Logeandose'}
if request.method == 'POST':
form = login_form(request.POST)
usuario = request.POST.get('username')
contrase = request.POST.get('password')
# Hacer el login
user = authenticate(username=usuario, password=contrase)
if user is not None and user.is_active:
login(request, user)
context['mensaje'] = u'Logeado como %s, contraseña %s' % (usuario, contrase)
else:
context['mensaje'] = u'No usuario o contraseña incorrecta'
return render (request, 'DjangoApp1/login.html', context)
And the models.py where I´ve the login form:
models.py
from django.contrib.auth.models import User
from django import forms
class login_form(forms.ModelForm):
username = forms.SlugField (max_length=8,
label='Usuario: ')
password = forms.SlugField (max_length=8,
widget=forms.PasswordInput(),
label='Contraseña:',
help_text='Hasta 8 letras')
class Meta:
model = User
fields = ('username', 'password')
You need to indent your class Meta because it's part of the model form class definition:
class login_form(forms.ModelForm):
username = forms.SlugField (max_length=8,
label='Usuario: ')
password = forms.SlugField (max_length=8,
widget=forms.PasswordInput(),
label='Contraseña:',
help_text='Hasta 8 letras')
class Meta:
model = User
fields = ('username', 'password')
Django doc explains this in details.