`from django.shortcuts import render, redirect
from .models import Contact
from django.contrib import messages
Create your views here.
def Contact(request):
if request.method == 'POST':
listing_id = request.POST['listing_id']
listing = request.POST['listing']
name = request.POST['name']
email = request.POST['email']
phone = request.POST['phone']
message = request.POST['message']
user_id = request.POST['user_id']
realtor_email = request.POST['realtor_email']
contact.save()
messages.success(
request, 'Your request has been submitted, a realtor will get back to you soon')
rn redirect('listings'+listing_id)
`
i'm trying to save the data from database. but give the error TypeError.
This statement
from .models import Contact
You have defined a method with the name Contact and you are trying to import a module from the .models and also it's name is Contact
So to fix the issue.
You need to change the Method name or import the module with any alias name.
for Eg:
from .model import Contact as contact_module
or change the method name to any like..
def contact_method(request):
#.....
Related
I want to validate my email field like: if email contains [gmail.com,outlook.com,yahoo.com] then I want to raise validation Error. But it's not working, I don't know what i am doing wrong. plz help me
views.py
from django.shortcuts import render
from django.views.generic import View
from access.utils import is_valid
from access.mixin import HttpResponseMixin
import json
from access.forms import Employer_Form
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
#method_decorator(csrf_exempt,name = 'dispatch')
class Emp_Registration_view(View,HttpResponseMixin):
def post (self,request,*args,**kwargs):
data = request.body
json_data = is_valid(data)
if not json_data:
return self.render_http_response(json.dumps({'msg':'Please send valid json only'}),status=400)
emp_data = json.loads(data)
form= Employer_Form(emp_data)
if form.is_valid():
form.save(commit=True)
return self.render_http_response(json.dumps({'msg':'Registered Successfully'}))
if form.errors:
return self.render_http_response(json.dumps(form.errors),status=400)
forms.py
from access.models import Employer_Registration
from django import forms
class Employer_Form(forms.ModelForm):
def clean_email(self):
email = self.cleaned_data['emp_email']
email_lists = ['gmail.com','yahoo.com','outlook.com','hotmail.com']
data = emp_email.split('#')
if data in email_lists:
raise forms.ValidationError("email is not valid")
return email
class Meta:
model = Employer_Registration
fields = '__all__'
Your method should be named clean_emp_email, because the field is named emp_email. Otherwise it won't be called.
Seems like you are splitting on # so if you split example#gmail.com it will be [example , gmail.com] and that you are comparing in this line exactly
if [example , gmail.com] in email_lists
so it is not found I suggest you to do you can omit splitting and find in substring as
for i in email_lists:
if i in self.cleaned_data['emp_email']:
raise forms.ValidationError("email is not valid")
After #Alexandr Tatarinov answer you should also call the clean_field_name or simply clean
I am currently building a small project using Django, I have noticed a problem that a logged in user was getting access to the other users page by simply changing the id in the url i.e
This is the url of currently logged in user
http://localhost:8000/home/myBooks/7/
by changing that id from 7 to 6
i.e
http://localhost:8000/home/myBooks/6/
He was getting access to that page,I have used #login_required for functional based views and LoginRequiredMixin for class based views ,but they are not helping, what else I need to do to prevent this problem?
My app/views.py:
from django.shortcuts import render,redirect
from django.http import HttpResponse
from django.views.generic.edit import FormView
from . forms import BookForm
from django.contrib.auth.models import User
from . models import UserBooks
from django.contrib.auth.models import User
from django.views import generic
from django.contrib.auth.decorators import login_required
from .models import UserBooks
from django.shortcuts import get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin
#login_required
def HomeView(request):
return render(request,'home/homepage.html')
class BookDetailsView (LoginRequiredMixin,generic.DetailView):
model=UserBooks
template_name='home/bookdetails.html'
class BooksView (LoginRequiredMixin,generic.DetailView):
model=User
template_name='home/mybooks.html'
#login_required
def addBooks(request):
if (request.method=='POST'):
form=BookForm(data=request.POST)
if(form.is_valid()):
u=UserBooks()
u.book_name=form.cleaned_data['book_name']
u.book_author=form.cleaned_data['book_author']
u.book_ISBN=form.cleaned_data['book_ISBN']
u.book_status=True
u.book_genre=form.cleaned_data['book_genre']
u.username=request.user.username
u.user_id = User.objects.get(username=request.user.username)
u.save()
return redirect('/')
else:
form = BookForm()
return render (request,'home/addbooks.html',{'form':form})
my apps/models.py:
from django.db import models
from django.contrib.auth.models import User
class UserBooks(models.Model):
user_id = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
username = models.CharField(max_length=200)
book_name = models.CharField(max_length=200)
book_author = models.CharField(max_length=200)
book_ISBN=models.CharField(max_length=200)
book_genre = models.CharField(max_length=200)
book_status=models.BooleanField(default=False)
class Meta:
unique_together = (("username", "book_ISBN"),)
def __str__(self):
return self.book_name
my apps/urls.py:
from django.urls import path
from . import views
app_name='home'
urlpatterns=[
path('',views.HomeView,name='home'),
path('addBooks/',views.addBooks,name='addBooks'),
path('myBooks/<int:pk>/',views.BooksView.as_view(),name='myBooks'),
path('<int:pk>/', views.BookDetailsView.as_view(), name='myBooks'),
]
If your view should always show the detail for the current user, don't put the ID in the URL at all; get the logged-in user directly within the view.
class BooksView(LoginRequiredMixin, generic.DetailView):
model = User
template_name ='home/mybooks.html'
def get_object(self):
return self.request.user
...
path('myBooks/',views.BooksView.as_view(),name='myBooks'),
class BooksView(LoginRequiredMixin, DetailView):
...
def get(self, request, *args, **kwargs):
current_user = User.objects.get(id=self.request.user.pk)
if current_user.pk == kwargs['pk']:
return HttpResponseRedirect('/')
else:
return HttpResponseRedirect('profile-url')
Here I assume that if you are logged in user and you try to check another user profile by giving id in url. So I add a get method which will check is requested URL id is for the current user (books/7/ is 7 is current user id) if not then redirect to an URL, for example, otherwise redirects to another url. You can get some idea. This may not help you exactly.
If you have just started to develop the app, then it is okay to use pks inside of urls. However, when it comes to a real working app it can lead to some security problems.
As you wrote, one can simply change the url and get some private data.
Other problems can be:
The number of users in the database can be easily counted by iteration through your urls.
The user can be easily detected by his id. Knowing it one can easily get some private data.
If you will decide to change ids in your db, then all the external links will be broken...and etc.
Considering that I suggest an approach in which you use ids internally. For external usage (urls, links) you can use uuids.
To do that you just need additional field into your model:
import uuid
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
And here is the example url:
url(r'^myBooks/(?P<user_uuid>\b[0-9A-Fa-f]{8}\b(-\b[0-9A-Fa-f]{4}\b){3}-\b[0-9A-Fa-f]{12}\b)/$',
After you switch to uuids it will be almost impossible to "hack" the url.
In my app I have 3 kind of users with different permissions. HR, Employees and candidate.
I would like to be able to create a User employee providing only its email ans set it as inactive And when the employee sign in into the app he setup a his first name, last name and a password and become Active on the app
I am starting in django and have really no idea how to do it;
I started the authentication process using the documentation and I get to :
views.py :
from django.shortcuts import render
from .forms import HRForm, CandidateForm, EmployeeForm
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.backends import ModelBackend
from .models import MyUser
def registerEmployee(request):
registered = False
if request.method == "POST":
Employee_form = EmployeeForm(data=request.POST)
if Employee_form.is_valid():
user = Employee_form.save()
user.set_password(user.password)
user.is_employee = True
user.save()
registered = True
else:
print("Error!")
else:
Employee_form = EmployeeForm()
return render(request,'Employee_registration_form.html',
{'Employee_form':Employee_form,
'registered':registered})
Could you please help me or give me direction to dive in ?
Thx you ;)
For activating/deactivating a user you could use:
user.is_active = False/True
For creating the user I recommend the following article:
https://medium.com/#ramykhuffash/django-authentication-with-just-an-email-and-password-no-username-required-33e47976b517
UPDATE!
The activation code is stored in the database, but I can not call it as a function of activation
Gives an error message:
TypeError at /account/activation/18d2ecbee1fd15440bbcfdf942c071a2f5b8d0ff/
activation() got an unexpected keyword argument 'activation_key'
forms.py
from django import forms
from django.contrib.auth.models import User
class EmailForm(forms.Form):
email = forms.EmailField(widget=forms.EmailInput(
attrs={'class': 'form-control input-lg',
'placeholder': 'Ваш E-mail'}))
views.py
import datetime
import hashlib
import random
from django.conf import settings
from django.contrib.auth import authenticate, logout, login
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from django.http import HttpResponseRedirect, HttpResponse
from django.http import Http404
from django.shortcuts import render
from forms import *
from models import *
def register(request):
if request.method == "POST":
form = EmailForm(request.POST)
if form.is_valid():
form_email = form.cleaned_data['email']
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
activation_key = hashlib.sha1(salt+form_email).hexdigest()
key_expires = datetime.datetime.today() + datetime.timedelta(2)
subject = 'Activation your e-mail'
from_email = settings.EMAIL_HOST_USER
to_email = [form_email]
message_email = "Hi, i'm link activate e-mail! \
http://127.0.0.1:8000/account/activation/%s" % activation_key
send_mail(subject,
message_email,
from_email,
to_email,
fail_silently=True)
code = ActivationEmail.objects.create(activation_key=activation_key)
code.save()
return render(request, 'registration/activate.html', locals())
else:
form = EmailForm()
return render(request, 'registration/register.html', locals())
def activation(request, code):
try:
active = ActivationEmail.objects.get(activation_key=code)
except ActivationEmail.DoesNotExist:
active = None
active.validated = True
if not active:
raise Http404
print "USER WAS HERE?!"
return HttpResponseRedirect('/account/wizard/')
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^register/', views.register, name='registration'),
url(r'^activation/(?P<activation_key>\w+)/', views.activation, name='activation'),
url(r'^login/$', views.user_login, name='login'),
url(r'^logout/$', views.user_logout, name='logout'),
Just can not figure out how to do next; (
You will need to
1- You will need to create a new table to store the activation keys, such that you can create a new entry before sending the email
2.- On the user clicking the activation link, that link should be sufficient for you to find the record you created before sending the email
3.- If everything matches, then set a user.is_active type thing on your user model.
But all that said, you are reinventing the wheel here. There are several top notch packages you can use with this and more. I would recommend django-allauth with also give you social login support (e.g. facebook). If you just want the activation portion, there is an older package called django-registration. There are a few others if you search around, but the point is you don't need to implement this (and you probably don't want to mess around with registration if you are not an expert)
This is my views.py
from django.conf import settings
from django.shortcuts import render_to_response
from django.template import RequestContext, loader
from django import forms
def TestLayer(request):
users = User.objects.all()
if request.method == 'POST':
form = TestForm(request.POST)
if form.is_valid():
user = form.cleaned_data['user']
rad1=form.cleaned_data['radio1']
rad2=form.cleaned_data['radio2']
test = Permission()
test.user = user
test.val = rad1 + rad2
test.save()
return render_to_response('testlayer.html',{'user':users})
else:
form = TestForm()
return render_to_response('testlayer.html', {'user':users})
This is my forms.py
from django import forms
from django.forms.widgets import RadioSelect
class TestForm(forms.Form):
user = forms.CharField(max_length=100)
RADIO_CHOICES1 = [['1','Radio 1'],['2','Radio 2']]
RADIO_CHOICES2 = [['3','Radio 2'],['4','Radio 2']]
radio = forms.ChoiceField( widget=RadioSelect(), choices=RADIO_CHOICES1)
radio = forms.ChoiceField( widget=RadioSelect(), choices=RADIO_CHOICES2)
My urls.py is this
url(r'^tests/','test.views.TestLayer',name='testlayer'),
When I click submit button the form is either not getting processed or its throwing a 404 error . Is my view correct according to the form and template ? I have generated the template from the forms .
There are a few things I noticed about your view and form code...
First, your TestForm class defines "radio" twice, instead of the two fields you're looking for in the form's cleaned data collection in the view: radio1, radio2
Second, you're not passing the form to the template in your view.
Third, there's no need to return render_to_response twice, or to even have the condition where you're creating a new instance of the test form. Instead try this:
#views.py
from django.conf import settings
from django.shortcuts import render #assumes Django 1.3
#these imports seem to be missing...
from your_app.forms import TestForm
from your_app.models import Permission
def test_layer(request):
users = User.objects.all()
form = TestForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
cleaned_data = form.cleaned_data
user = cleaned_data.get('user')
radio1 = cleaned_data.get('radio1')
radio2 = cleaned_data.get('radio2')
test = Permission()
test.user = user
test.val = radio1 + radio2
test.save()
return render(request, 'testlayer.html', {'user':users, 'form' : form})
#forms.py
from django import forms
class TestForm(forms.Form):
user = forms.CharField(max_length=100)
RADIO_CHOICES1 = [['1','Radio 1'],['2','Radio 2']]
RADIO_CHOICES2 = [['3','Radio 2'],['4','Radio 2']]
radio1 = forms.ChoiceField( widget=forms.RadioSelect(), choices=RADIO_CHOICES1)
radio2 = forms.ChoiceField( widget=forms.RadioSelect(), choices=RADIO_CHOICES2)
Also, your URL pattern doesn't end with $, and you can prefix your patterns to avoid repeating the path to your view function(s):
#urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('test.views',
url(r'^tests/$','test_layer', name='testlayer'),
)
Lastly, your view function name was title-cased: TestLayer. In Python, it's a convention that function names, variables, etc, are lower-cased with underscores separating words, and classes are title-cased.
Hope that helps you out.