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.
Related
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
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})
I am trying to make quiz making application, since am new to django am unable to build the logic for saving foreign key field in database table. Someone please help me for the same.
models.py
In models.py , class quiztitle is for title of the quiz and id(foreign key,User model) of user who created that quiz.
class question is for question along with 4 options and the correct answer. Quizid(foreign key,quiztitle model) and id(foreign key,User model)
class answer is for the answer submitted by user who take the quiz.
from django.db import models
from django.contrib.auth.models import User
class quiztitle(models.Model):
Quiz_id = models.AutoField(primary_key=True)
Quiz_title = models.CharField(max_length=600)
id= models.ForeignKey(User, on_delete=models.CASCADE)
class question(models.Model):
Qid = models.AutoField(primary_key=True)
id = models.ForeignKey(User,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle,on_delete=models.CASCADE)
Qques = models.TextField()
Qoption1 = models.TextField()
Qoption2 = models.TextField()
Qoption3 = models.TextField()
Qoption4 = models.TextField()
QAnswer = models.TextField()
class answer(models.Model):
Ansid = models.AutoField(primary_key=True)
Qid = models.ForeignKey(question,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
id = models.ForeignKey(User, on_delete=models.CASCADE)
Answer = models.TextField()
forms.py
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email','password1','password2']
views.py
from django.shortcuts import render,redirect,HttpResponseRedirect
from .models import question ,quiztitle
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.forms import inlineformset_factory
from django.contrib.auth.forms import UserCreationForm
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
# Create your views here.
#login_required(login_url='home')
def handle_quiz(request):
if request.method=="POST":
# get post parameters
id = request.POST.get('id')
Quiz_title = request.POST.get('Quiz_title')
Quiz_id = request.POST.get('Quiz_id')
Qid = request.POST.get('Qid')
Qques = request.POST.get('Qques')
Qoption1 = request.POST.get('Qoption1')
Qoption2 = request.POST.get('Qoption2')
Qoption3 = request.POST.get('Qoption3')
Qoption4 = request.POST.get('Qoption4')
QAnswer = request.POST.get('QAnswer')
#I guess here is the mistake in saving the data in the mysql database
title = quiztitle(Quiz_title=Quiz_title,Quiz_id=Quiz_id,id=id)
title.save()
detail = question(Qid=Qid,Quiz_id=Quiz_id,id=id,Qques=Qques,Qoption1=Qoption1,Qoption2=Qoption2,Qoption3=Qoption3,Qoption4=Qoption4,QAnswer=QAnswer)
detail.save()
messages.success(request,"Your question has been added succesfully ")
return HttpResponseRedirect('/quizmaker')
return render(request,"createquiz.html")
def logoutUser(request):
logout(request)
return redirect('home')#redirect to login page
def home_page(request):
return render(request,'Home.html')
def registerPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
messages.success(request, 'account has been created successfully for username' + username)
return redirect('login')
context = {'form':form}
return render(request,'register.html',context)
def handle_login(request):
if request.user.is_authenticated:
return redirect('home')
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('quizmaker')
else:
messages.info(request, 'Incorrect Username or Password')
context = {}
return render(request, 'login.html', context)
#login_required(login_url='login')
def handle_response(request):
data= question.objects.all()
return render(request, "student.html", {"messages": data})
admin.py
from django.contrib import admin
from .models import *
# Register your models here.
class quizadmin(admin.ModelAdmin):
list_display = ['Qid','Quiz_id','Qques','Qoption1','Qoption2','Qoption3','Qoption4','QAnswer']
admin.site.register(question,quizadmin)
admin.site.register(quiztitle)
As you guess your issue lies at title and detail.
To set a value to the ForeignKey you need an object. You can use instead an field with _id at the end.
Behind the scenes, Django appends "_id" to the field name to
create its database column name, see Django ForeignKey
It must be:
title = quiztitle.objects.create(
Quiz_title=Quiz_title,
Quiz_id=Quiz_id,
User_id_id=id # here
)
detail = question.objects.create(
Quiz_id_id=Quiz_id, User_id_id=id # and here,
Qid=Qid, Qques=Qques, Qoption1=Qoption1,
Qoption2=Qoption2, Qoption3=Qoption3,
Qoption4=Qoption4, QAnswer=QAnswer
)
I suggest you to use Django ModelForm here.
Based on the above, I recommend you also to rename your ForeignKey fields:
id > to user
Quiz_id > to quiztitle
Model style (Django Docs):
Use InitialCaps for class names (or for factory functions that return
classes).
Field names should be all lowercase, using underscores instead of
camelCase.
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.