Why am I getting an AttributeError? - python

I'm trying to store the first name and last name of a user in my datatbase upon hitting the submit button so that next time when I manually check in Terminal what's inside my database, I can see exactly what the user inputted.
This is the error I'm getting:
I'm assuming the error is coming from my views.py file:
from django.http import HttpResponse
from .models import Person
from django.shortcuts import render
def index(request):
if request.method == 'POST':
first_name = request.POST.get('firstName')
last_name = request.POST.get('lastName')
if first_name and last_name:
user = Person.objects.create(firstName=first_name, lastName=last_name)
user.save()
return render('request', 'music/index.html')
def detail(request, user_id): # Testing out page 2
return HttpResponse("<h2>Page # (testing this out) " + str(user_id) + "</h2>")

The code is passing 'request' (string literal) to django.shortcuts.render which expected Request object as the first parameter.
Pass the request parameter of the view function:
return render('request', 'music/index.html')
should be:
return render(request, 'music/index.html')

Related

Passing Id and Context in Django Redirect

I want to pass a model to a html page as context when I login into an account.
My Home page url comes with user id as a url parameter.
But i cant pass any context in redirect
views.py
from django.contrib.auth import authenticate,login,logout
from django.contrib import messages
from django.shortcuts import redirect, render
from django.http import HttpResponse
from .models import users
from home.models import Posts
def f1(request):
Post = Posts.objects.all()
context = {'Post':Post}
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
uz = authenticate(request,username=username, password=password)
if uz is not None:
login(request,uz)
id = users.objects.filter(name=username).values('id')[0]['id']
return redirect('home',id) # This Works Fine
return redirect('home',id,context) # This is not Working
else:
messages.error(request,"Wrong Credentials")
return render(request,'login.html')
urls.py
from django.contrib.auth import logout
from django.urls import path
from . import views
urlpatterns=[
path('<str:users_id>/',views.func,name="home"),
]
How can I pass the context?
If I can't tell me an alternative way to do it.
You're redirecting to another view, so you're passing data through your url. You can't put your context in it, so you can directly render your template :
return render(request, "home.html", context)
If you really want to redirect to another url, as your context only contains all Post objects, you can build it in your home view.
Then you have :
f1 :
return redirect('home',id)
func :
context = {'Post': Posts.objects.all()}
return render(request, "home.html", context)
Add the id to your context dictionary and pass to redirect. Something like
context = {'Post':Post, 'Id':id}
return redirect('home', context)
#Balizok is correct: you can't pass context via the URL, without urlencoding it, which would be a bad idea for large amounts of data. If you need the home page to show posts or not show posts depending on whether the user has just logged in, you could do it in a few ways:
Show posts only if the user is logged in:
def home(request, id):
context = {}
if request.user.is_authenticated:
context["Post"] = Posts.objects.all()
return render(request, "home.html", context)
Show posts only if the user has just been redirected from the login page via a query parameter:
from django.url import reverse
def f1(request):
# ... log the user in etc.
url = reverse("home", id) + "?show_posts=true"
return redirect(url)
def func(request, id):
context = {}
if request.GET.get("show_posts") == "true":
context["Post"] = Posts.objects.all()
return render(request, "home.html", context)
Show posts only if the user has just been redirected from the login page via the session:
from django.url import reverse
def f1(request):
# ... log the user in etc.
request.session["show_posts"] = True
return redirect("home", id)
def func(request, id):
context = {}
if request.session.get("show_posts"):
context["Post"] = Posts.objects.all()
return render(request, "home.html", context)

Check for password before accessing content in django

I am trying to build a functionality where users have to enter the passcode to access the site.
If you go to this site it will ask for a password (123) before showing you the content:
https://www.protectedtext.com/djangoproj
I want to do it without forms.py.
URL OF THE PAGE --> TEMPLATE --> ASK FOR PASSCODE --> SHOW CONTENT IF PASSCODE MATCHES
models.py
from django.db import models
# Create your models here.
class Text(models.Model):
text = models.TextField(blank=True)
slug = models.SlugField(unique=True)
password = models.CharField(max_length=50)
def __str__(self):
return self.slug
views.py
from django.shortcuts import render
from .models import Text
import django.contrib.auth
# Create your views here.
def textview(request, slug):
obj= Text.objects.get(slug=slug)
return render(request, 'text/textpage.html', {'obj' : obj})
def home(request):
return render(request, 'text/index.html', {})
I have tried creating a new template for password but I am still not getting that functionality.
Thanks in advance
If I were you (and didn't want to use DRF), I would make something like this:
def check_password(*args, **kwargs): # decorator function for checking password
def wrapper(func):
if kwargs.get('password', None) == '123':
func() # show index, if password is corrent
else:
raise Exception('Access denied') # else raise the exception
return wrapper
def home(request):
try:
password = request.GET.get('password') # get password from given parameters
#check_password(password)
def show_index(): # create function, maybe better to make it out of scope
return render(request, 'text/index.html', {})
show_index() # call function
except:
print('Password was not given or it is incorrect, access denied')
return render(request, 'text/401.html', {})

Why am I getting this error "local variable 'text' referenced before assignment"

I am trying to create a share function using python and Django and when I run "share" it gives me back an error. Here's my code:
views.py
from django.shortcuts import render
from basicapp.forms import UserForm, UserProfileInfoForm, PostForm
from django.contrib.auth.models import User
from basicapp.models import UserProfileInfo
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth import login,logout,authenticate
#login_required
def user_post(request):
form = PostForm(request.POST)
if form.is_valid():
text = form.cleaned_data['post']
form = PostForm()
return HttpResponseRedirect(reverse('index'))
else:
HttpResponse("Not Valid try dat boi agian")
render(request, 'basicapp/userpost.html',
{'form':form,
'text':text})
forms.py
class PostForm(forms.Form):
post = forms.CharField(max_length=256)
This is the error:
You're not returning the HttpResponse in your else block execution continues to next line of code which wants a text variable to be defined, but since the is_valid block never ran, there is no text in scope.
You will also never get to the final line once you have a return in both the if and else branches of the form.is_valid() test.
def user_post(request):
form = PostForm(request.POST)
if form.is_valid():
text = form.cleaned_data['post']
form = PostForm()
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse("Not Valid try dat boi agian") # return here
return render(request, 'basicapp/userpost.html', # should return here too but this line will never run
{'form':form,
'text':text})

login_required django decorator

I wanted to use login_required with function based views.I gone through Django's official docs of django.contrib.auth.decorators.login_required. I could not grab it clearly.
Issue is , the control is returning back to login function even though user is already authenticated instead of going to home page.
What else changes are required to allow login using my code?
def login(request):
"""
"""
data_dict = {}
if request.POST:
req_dict = dict(zip(request.POST.keys(), request.POST.values()))
accmgr = AccountManager()
user = accmgr.validate_user(**req_dict)
if user:
ret = redirect('homepage')
else:
data_dict["msg"] = "Username or password is incorrect!"
ret = render(request, "login.html", data_dict)
else:
ret = render(request, "login.html", data_dict)
return ret
#login_required(login_url='/login')
def homepage(request):
'''
'''
return render(request, "adminpage.html", {"title":"Hello World"})
NOTE : accmgr.validate_user internally checks user.is_authenticated.There are some other checks I had to do to allow user so added custom function.
Also added LOGIN_URL in settings.py
LOGIN_URL ='/login/'
login_required decorator checks if request.user.is_authenticated() returns True. Probably the issue is, accmgr.validate_user method does not really authenticate the user.
You should call authenticate() instead, to actually log user in.
from django.contrib.auth import login as django_login
from django.contrib.auth import authenticate
def login(request):
...
req_dict = request.POST.copy()
user = authenticate(
username=req_dict['username'], password=req_dict['password'])
if user:
django_login(request, user)
...
Please see documentation for more information.

Using data from one view function in another with Django (forms)

I am currently using Django to have users enter data using a form. Using my views.py file, I was able to write a views function that stores the data users enter. However. What I want to do, is take the data the users has enter and use it in another views function in my "views.py" file.
For example, here is my views.py file:
def s(request):
if request.method == 'POST':
search = Search(data=request.POST)
if search.is_valid():
success = True
name = search.cleaned_data['search']
else:
print search.errors
else:
search = Search()
return HttpResponse(name)
What I'd then like to do is create a second view function and be able to call the "name" variable defined above. Anyone know how I could go about doing this? Thanks.
Not sure what you want to do in the second view. Try passing parameters.
from django.shortcuts import render
from django.http import HttpResponseRedirect
def s(request):
search = Search()
if request.method == 'POST':
search = Search(data=request.POST)
if search.is_valid():
return HttpResponseRedirect('/second-url/?name=%s' %(search.cleaned_data['search'],))
return render(request, 'template_name', {'form': search})
def s2(request):
name = request.GET.get('name')
return HttpResponse('hello %s' % name)

Categories

Resources