I have recently started to learn and play around Flask. I am following the Corey Schafer's
tutorial on Youtube. For creating a registration form he uses PasswordField from flsk-wtf package. I followed the instruction carefully but whenever I set the methods as 'POST' an 'GET' for register method within the main.py file, I get the following error:
ImportError: The crypt module is not supported on Windows
Here is the form.py:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo
from werkzeug.security import generate_password_hash, check_password_hash
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=2,max=14)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired(message="Please Enter a Password")])
confirm_password = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sign Up')
class LoginForm(FlaskForm):
email = StringField('Username',
validators=[DataRequired(), Length(min=2,max=14)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
remember = BooleanField('Remember Me')
submit = SubmitField('Login')
and here is the main.py:
from crypt import methods
from flask import Flask, render_template, url_for
from forms import RegistrationForm, LoginForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'd64d7355a7118a8591b4a954c0112edc'
posts =[
{
'author': 'max jordan',
'title': 'Falsk blog',
'content': 'First post content',
'Date_posted': 'April 22, 2022'
}
]
#app.route('/')
#app.route('/home')
def home():
return render_template('home.html', posts = posts)
#app.route('/about')
def about():
return render_template('about.html')
#app.route('/register', methods=['POST', 'GET'])
def register():
form = RegistrationForm()
return render_template('register.html', title = 'Register', form = form)
#app.route('/login')
def login():
form = LoginForm()
return render_template('login.html', title = 'Login', form = form)
It is worth mentioning that I am working with windows 10.
Thank you in advance
Related
I've created a usercreationform and try to check if username and email is already exist in database or not. Here It only check for email if it is exist or not but it cannot check for the username.
Views.py
from django.shortcuts import render,redirect
from . forms import signupform
from django.contrib import messages
from django.contrib.auth import login,authenticate,logout
from django.contrib.auth.models import User
def signup_data(request):
form = signupform(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
if User.objects.filter(username=username).exists():
messages.error(request,'Username is already taken')
return redirect('signup')
elif User.objects.filter(email=email).exists():
messages.error(request,'Email is already taken')
return redirect('signup')
else:
form.save()
messages.success(request,'Account Is Created')
return redirect('signup')
return render(request,'login_module/signup.html',{'form':form, 'message': messages})
Forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User class signupform(UserCreationForm):
username= forms.CharField(max_length=10,widget=forms.TextInput(attrs={'class':'form-control'}))
first_name = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=20,widget=forms.TextInput(attrs={'class': 'form-control'}))
email = forms.EmailField(max_length=20,widget=forms.EmailInput(attrs={'class': 'form-control'}))
password1 = forms.CharField(label="Password",widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2 = forms.CharField(label="Confirm Password",widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = User
fields = ['username','first_name','last_name','email','password1','password2']
You can combine both the queries to run a OR query using Q for that:
from django.db.models import Q
if User.objects.filter(Q(username=username)|Q(email=email)).exists():
# do stuff
I have two different forms in my register page as the one to one relationship in one of the model will show a drop down box therefore I am using the second models field where the user will have to input the field.
How would I make it so when the forms are valid, the 'SNI' will save to the first form and not the second.
Model
from asyncio import FastChildWatcher
import email
from pyexpat import model
from xxlimited import Null
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class userCouncil(BaseUserManager):
def create_user(self, userID, password=None):
if not email:
raise ValueError("Email is required")
user = self.model(userID = self.normalize_email(userID))
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, userID, password):
user = self.model(userID = self.normalize_email(userID))
user.set_password(password)
user.is_staff = True
user.is_admin = True
user.save(using=self._db)
return user
class sni(models.Model):
SNI = models.CharField(max_length=256, primary_key=True)
Used = models.IntegerField(null=True, blank=True)
password = None
USERNAME_FIELD = 'SNI'
def __str__(self):
return self.SNI
class Account(AbstractBaseUser):
userID = models.EmailField(primary_key= True ,max_length=256, unique=True)
name = models.CharField(max_length=100)
dateOfBirth = models.DateField(max_length=8, null=True)
homeAddress = models.CharField(max_length=100, null=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
sni = models.OneToOneField(sni, on_delete=models.CASCADE, null=True, blank=True)
USERNAME_FIELD = 'userID'
objects = userCouncil()
def __str__(self):
return self.userID
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
Forms
import email
from pprint import isreadable
from pyexpat import model
from statistics import mode
from tabnanny import check
from xxlimited import Null
from attr import field
from django.forms import ModelForm, forms, widgets
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from matplotlib import use
from matplotlib.style import context
from .models import Account, sni
class createUserForm(UserCreationForm):
class Meta:
model = Account
fields = ['userID','name','dateOfBirth','homeAddress','password1','password2', 'sni']
def clean_userID(self):
userID = self.cleaned_data['userID'].lower()
u = self.cleaned_data['userID']
check_existing = Account.objects.filter(userID=userID).exists()
if check_existing:
raise forms.ValidationError("The following userID already exists: " + u)
else:
return userID
class SNIForm(UserCreationForm):
class Meta:
model = sni
fields = ['SNI', 'Used']
class AccountAuthenticationForm(forms.ModelForm):
password = forms.CharField(label = "password", widget = forms.PasswordInput)
class Meta:
model = Account
fields = ('userID', 'password')
Views
from django.shortcuts import redirect, render
from django.http import HttpResponse
from matplotlib import use
from matplotlib.pyplot import get
from matplotlib.style import context
from werkzeug import Request
from .models import *
from django.contrib.auth.hashers import make_password, check_password
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages
from django.contrib.auth import authenticate
from django.contrib.auth import login as dj_login
from django.forms import ModelForm, forms
from django.contrib.auth.decorators import login_required
from .forms import AccountAuthenticationForm, SNIForm, createUserForm
def login(request):
context = {}
if request.method == 'POST':
username = request.POST.get('username').lower()
password = request.POST.get('password')
user = authenticate(request, userID = username, password = password)
form = AccountAuthenticationForm(request.GET)
if user is not None:
dj_login(request, user)
return redirect('dashboardPage')
else:
messages.info(request, "userID or password is incorrect")
return render(request, 'base.html', context)
def registerPage(request):
form = createUserForm()
form2 = SNIForm()
if request.method == 'POST':
form = createUserForm(request.POST)
form2 = SNIForm(request.POST)
if form.is_valid() and form2.is_valid:
print(form2['SNI'].value)
form.save()
form2.save()
userID = form.cleaned_data.get('userID')
messages.success(request, "Account created for: " + userID)
return redirect('loginPage')
context = {'form' : form, 'form2' : form2}
return render(request, 'register.html', context)
#login_required(login_url='loginPage')
def dashboardPage(request):
context = {}
return render(request, 'dashboard.html', context)
In views please refer to the registerPage function. Thank you
What the first form can take is Sni_id.
There is no sni_id without first saving an sni instance.
What you can do is...
Save both forms
f=form.save()
f2=form2.save()
f2.instance.user = f.instance.id
UPDATE:
if form2.is_valid():
sni = form2.data["sni"]
used = form2.data["used"]
if SNI.objects.filter(sni=sni, used=used).exists()
f=form.save()
i have setup the forms in the frontend what i want is that any User if gives his username for example username-> helloworld then it is interpreted as #helloworld and then this form with changed #username should be saved in the database so that i can use it afterwards.....
i am a noob in django framework .
i have been trying since last 2 days to find a answer here and by using google but unable to find a helpful answer
here is my ->forms.py
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
class Meta:
model = User
fields = ['first_name','last_name','username', 'email', 'password1', 'password2']
this is my -> views.py file
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate
from django.contrib import messages
from django.contrib.auth.models import User
from .forms import SignUpForm
from django.contrib.auth import get_user_model
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import EmailMessage
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
UserModel = get_user_model()
#index and signin def have been removed because it is out of context of question
def signup(request):
if request.user.is_authenticated:
return redirect('index')
else:
form = SignUpForm()
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
User.username = "#{}".format(User.username)
user.is_active = False
user = form.save
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate your account.'
message = render_to_string('activation_mail.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': default_token_generator.make_token(user),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
return HttpResponse('Please confirm your email address to complete the registration')
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
Just override your form's save method to alter the data before saving.
class SignUpForm(UserCreationForm):
class Meta:
model = User
fields = ['first_name','last_name','username', 'email', 'password1', 'password2']
def save(self, *args, **kwargs):
self.instance.username = f"#{self.instance.username}"
return super().save(*args, **kwargs)
I will like to be able to send files in email in this django project. But files with spacies in their names seem not to go through, also when selecting the files to be sent i am able to select multiple files but only one file will go through the others are not recieved in mail.
Views.py
import os
from django.shortcuts import render, redirect
from django.core.files.storage import FileSystemStorage
from .forms import EmailForm
from django.core.mail import send_mail
from django.conf import settings
from datetime import datetime
from django.core.mail import EmailMessage
def email1(request):
if request.method == "POST":
form = EmailForm(request.POST, request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.published_date = datetime.now()
post.save()
email = request.POST.get('email')
subject = request.POST.get('subject')
message = request.POST.get('message')
document = request.FILES.get('document')
email_from = settings.EMAIL_HOST_USER
recipient_list = [email]
email = EmailMessage(subject,message,email_from,recipient_list)
base_dir = 'media/documents/'
try:
for i in document:
email.attach_file('media/documents/'+str(document))
os.rename(document(document.replace(' ', '_')))
email.send()
return render(request, 'sendmail/sendmail.html')
except:
pass
else:
form = EmailForm()
return render(request, 'sendmail/sendmail.html', {'form': form})
forms.py
from django import forms
from django.forms import ClearableFileInput
from .models import Mails
class EmailForm(forms.ModelForm):
email = forms.EmailField(max_length=200, widget=forms.TextInput(attrs={'class': "form-control", 'id': "clientemail"}))
message = forms.CharField(widget=forms.Textarea(attrs={'class': "form-control"}))
document = forms.FileField(widget = forms.ClearableFileInput(attrs={'multiple':True}))
subject = forms.CharField(widget=forms.TextInput(attrs={'class': "form-control"}))
class Meta:
model = Mails
fields = ('email', 'subject', 'message', 'document',)
models.py
from django.db import models
class Mails(models.Model):
email = models.EmailField()
subject = models.CharField(max_length=1000)
message = models.CharField(max_length=20000)
document = models.FileField(upload_to='documents/')
def __str__(self):
return self.email
I am unable to send mail on django application using office365 settings
my settings for the email service.
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.office365.com'
EMAIL_HOST_USER = "***********"
EMAIL_HOST_PASSWORD = '***********'
EMAIL_PORT = 587
My models.py
from django.db import models
from django import forms
from django.core.validators import RegexValidator
class ContactModel(models.Model):
contact_name = models.CharField("Your Name ",max_length=20)
contact_email = models.EmailField("Your Email ")
content = models.TextField("Message ",max_length=1500)
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
message="Please Enter a valid Contact number(in +999999) format'. Up to 15 digits allowed Minimum 9 digits.")
phone_number = models.CharField("Contact Number(in +9999 format)",validators=[phone_regex], max_length=17, blank=True) # validators should be a list
needacallback = models.BooleanField(" I want an Informational Phone Call")
My views.py
from django.shortcuts import render,render_to_response
from . import forms
from django.core.mail import EmailMessage
from django.shortcuts import redirect
from django.template.loader import get_template
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.http import HttpResponse
from django.views.decorators.csrf import ensure_csrf_cookie
def home(request):
form = forms.ContactForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
# form = form_class(data=request.POST)
if form.is_valid():
contactform = form.save(commit=False)
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
needacallback = request.POST.get(
'needacallback'
, '')
phone_number = request.POST.get(
'phone_number'
, '')
form_content = request.POST.get('content', '')
# Email the profile with the
# contact information
template = get_template('contact_template.html')
context = {
'contact_name': contact_name,
'contact_email': contact_email,
'form_content': form_content,
'phone_number': phone_number,
'needacallback': needacallback,
}
content = template.render(context)
if needacallback:
subject = "This person requested for a call"
else:
subject = "New Message from " + contact_name
email = EmailMessage(
subject,
content,
"Contact me" + '',
['myemail#gmail.com'],
headers={'Reply-To': contact_email}
)
email.send()
contactform.save()
return redirect('thanks')
return render(request, 'index.html', {
'form': form,
})
def thanks(request):
return render(request, 'thanks.html')
The error I am facing is
SMTPSenderRefused at / (501, b'5.1.7 Invalid address
[MAXPR01MB0396.INDPRD01.PROD.OUTLOOK.COM]', '=?utf-8?q?Your?=')
Template is a normal contact form which is formed by form.as_p()
As the error points out, you have incorrect sender address. According to the docs it's 3rd argument as in this example:
from django.core.mail import send_mail
send_mail(
'Subject here',
'Here is the message.',
'from#example.com',
['to#example.com'],
fail_silently=False,
)
Also this answer might be useful if you want to add the sender name to the script.