Backend Validation error message using django - django-models

While Giving Correct username and password in login page its working correctly,while giving wrong username and password,how to show the error message.
views.py
def user_login(request):
logout(request)
username = password = ''
username = request.POST.get('username')
print(username)
password = request.POST.get('password')
print(password)
if request.POST:
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
auth_login(request, user)
return render(request, 'admin_pannel.html', { 'dept' : dt, 'ds' : ds })
return redirect('/dashboard/')
return render(request, 'registration/login.html', {'dt' : dt })

Error messages are usually handled by an instance of django.forms.forms.Form. For your view I would suggest something like this:
from django.contrib.auth.forms import AuthenticationForm
def user_login(request):
if request.method == 'POST':
logout(request)
form = AuthenticationForm(request.POST)
if form.is_valid():
user = form.get_user()
auth_login(request, user)
return render(request, 'admin_pannel.html', {...})
else:
form = AuthenticationForm()
return render(request, 'registration/login.html', {'form': form, ...})
A quick glance at AuthenticationForm.clean looks like it will accomplish the same thing that you are doing in your view.
The only other thing that comes to mind is Django's messages framework, but I don't think that would be your best option.

Related

Django - save form into database

Hey guy I need your help
so I have this model:
class PreferedShops(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
shop = models.ForeignKey(Shops, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.user.username, self.shop.name
and this is the form:
class LikeShopForm(forms.ModelForm):
class Meta:
model = PreferedShops
fields = ['date_posted']
and this is the view:
def shops(request):
if request.method == 'POST':
form = LikeShopForm(request.POST)
if form.is_valid():
u = form.save(commit=False)
u.user = request.user
u.shop = request.shop
u.save()
return redirect('shops')
else:
form = LikeShopForm()
return render(request, "shops.html", {'form': form})
the probleme that I have is when I click on Like Button, I want that the form takes automatically the user and the name of the shop, and then save them into the DB
the user and the shop's name should be hidden
when I click submit I have this error 'WSGIRequest' object has no attribute 'shop'
please help me to take the shop's name automatically and save it in the db
Well the shop is not part of the request (strictly speaking, user is not either, but it is frequently added to the request object in the middelware by looking at the session).
You thus need to encode it into the URL, or in the POST parameters. For example with:
# app/urls.py
from django.urls import path
from app.views import like_shop
urlpatterns = [
path('shop/<int:shop_id>/like', like_shop, name='like_shop'),
]
Then in the view we obtain a parameter shop_id that contains the id of the related Shops object:
from django.shortcuts import get_object_or_404
from app.models import Shops
def like_shop(request, shop_id):
if request.method == 'POST':
shop = get_object_or_404(Shops, id=shop_id)
form = LikeShopForm(request.POST)
if form.is_valid():
u = form.save(commit=False)
u.user = request.user
u.shop = shop
u.save()
return redirect('shops')
else:
form = LikeShopForm()
return render(request, "shops.html", {'form': form, 'shop_id': shop_id})
Then the request in the POST should point to:
<!-- shops.html -->
<form action="{% url 'like_shop' shop_id=shop_id %}" method="post">
<!-- ... -->
</form>
The URL to this page then thus looks like /shops/123/like with 123 the id of the shop. If you thus want to pass the shop "implicitly", you need to encode it in the URL. Otherwise, you should make it a field of the form, such that the user can pick an option. Personally I find it very strange that you use date_posted as a form field, since typically this is an field that I would expect to be filled in with the timestamp when the user likes the shop.
Note: the name of the models is normally singular, so Shop instead of Shops.

SQLAlchemy error "on delete"

i´m new to Flask and i´m trying to delete a user.
I can already create a user, it is saying that 1 argument is missing:
add_user.html
<form method="POST" action="/del_user">
<label> ID: </label>
<input id="id" name ="id" type="text" />
<input type="submit" value="Delete"/>
</form>
app.py
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
#Set the application in debug mode so that the server is reloaded on any code change & helps debug
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:********#localhost/projetofinal'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
#app.route('/')
def index():
return render_template('add_user.html')
#app.route('/post_user', methods=['POST'])
def post_user():
user = User(request.form['username'], request.form['email'])
db.session.add(user) #add object
db.session.commit() #save
return redirect(url_for('index'))
#app.route('/del_user', methods=['POST'])
def del_user():
user = User(request.form['id']) #ERROR LINE
user1 = db.session.query(User).filter(User.id==user.id).first()
db.session.delete(user1)
db.session.commit()
return redirect(url_for('index'))
if __name__=="__main__":
app.run()
TypeError: init() missing 1 required positional argument: 'email'
Just get the id from the form, turn it into an integer and query the database for it.
#app.route('/del_user', methods=['POST'])
def del_user():
user = int(request.form['id'])
user1 = db.session.query(User).filter(User.id==user.id).first()
db.session.delete(user1)
db.session.commit()
return redirect(url_for('index'))
Additionally check if your db query returns a user object to make sure you don't attempt to delete a non existent user and get another error
if user1:
db.session.delete(user1)
else:
flash('the record requested was not found')
return redirect(url_for('index'))
see how to use flash here to show error messages etc elegantly
Lastly, Instead of deleting using text input, you can use select that uses already existing users so that the value is the user id and the option text is the user name to make sure attempt to delete only uses existing user ids

How can I do a manually login method with my own model? Django

I want to do a manual log in method with my own model I read the documentation but I don't understand how to use
this:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
this is my model Usuario:
class Usuario(models.Model):
id_usuario = models.AutoField(primary_key=True)
nombre = models.CharField(max_length=255)
correo_electronico = models.EmailField()
direccion = models.CharField(max_length=255)
telefono = models.CharField(max_length=50)
usuario = models.CharField(max_length=255)
contrasenia = models.CharField(max_length=255, null=True ,blank=True)
id_perfil = models.ForeignKey(Perfil, on_delete=models.CASCADE)
fecha_creacion = models.DateTimeField(auto_now_add=True)
fecha_modificacion = models.DateTimeField(null=True)
fecha_cancelacion = models.DateTimeField(null=True)
status = models.CharField(max_length=50)
def __str__(self):
return '{}'.format(self.nombre)
Your view is meant to be used for default authentication system. But, given your user model, I think you are looking for custom authentication system. It is best to see Django docs. In short, you need a custom model, forms, and backends. You should also make sure your settings.py specifies which backend Django is supposed to look for.

Django session with angular.js

I have set a view Index(View) to load a view for angular and it works fine. Angular communicates with Django and maintains session (Token base).
class Index(TemplateView):
context = {}
permanent = False # docs.djangoproject.com/en/1.9/ref/class-based-views/base/
template_name = 'index.html'
def __init__(self):
self.context = _.default_context()
self.response = _.default_response()
def get(self,request, *args, **kwargs):
return _.render_view(request, self.template_name, self.context)
def post(self, request, *args, **kwargs):
_.process_request(request)
print request.POST
username = request.POST['username']
password = request.POST['password']
print password
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
auth_token,_ignore = Token.objects.get_or_create(user=user)
self.response['status']=True
self.response['statusCode']=200
self.response['data'] = {'token':auth_token.key}
self.response['user'] = {'email' : user.email,
'first_name' : user.first_name,
'last_name' : user.last_name}
else:
self.response['status']=False
self.response['statusCode']=203
self.response['data']=[]
else:
self.response['status']=False
self.response['statusCode']=404
self.response['data']=[]
return _.serialize_response(self.response)
Now anyone can access this page. I want to restrict user to access dashboard without login (in the case a user tries to hack by adding cookie or something).
If I create separate pages for login and angular:
How can I handle different pages in one angular app?
Do I have to create angular app intent?
Something in Django?

Django ImageField Upload

I am trying to use Django ImageField to allow a user to upload a profile picture. However, after browsing for the image, when I attempt to update the profile, the picture upload changes from the file name to "No file selected" and I receive "This file is required" error.
If it helps, I was following along with this tutorial. I do understand that he uses two character fields, but I was attempting to change it to handle FileFields. From other questions such as this one on stack overflow, I know that the form requires a request.FILES as well.
Here is my Views.py.
#login_required
def user_profile(request):
if request.method == 'POST':
form = UserProfileForm(request.POST, request.FILES, instance=request.user.profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/loggedin')
else:
user = request.user
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('profile.html', args)
Additionally, I have these two lines in my settings.
AUTH_PROFILE_MODULE = 'userprofile.UserProfile'
MEDIA_ROOT = 'E:\Pictures\django_stuff'
Let me know if there is anything else that is required.
As requested by Erny
Forms.py
from django import forms
from models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('logo', 'description')
Models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
logo = models.ImageField(upload_to = 'photos')
description = models.TextField()
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

Resources