page opening even if not logged in, Django - python

I have made a small project.
User first logs in then he is redirected to the home page.
But if a user has not logged in then also that homepage is opening if we paste the url of that home page.
I have tried many things given on net but it's not working.
This is my urls.py
from django.conf.urls import url
from django.contrib import admin
from blog import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.login, name='login'),
url(r'^register/$', views.register, name='register'),
url(r'^home/$', views.home, name='home'),
url(r'^javaq/$', views.javaq, name='javaq'),
url(r'^javar/$', views.javar, name='javar'),
url(r'^csq/$', views.csq, name='csq'),
url(r'^csr/$', views.csr, name='csr'),
url(r'^cq/$', views.cq, name='cq'),
url(r'^cr/$', views.cr, name='cr'),
url(r'^cppq/$', views.cppq, name='cppq'),
url(r'^cppr/$', views.cppr, name='cppr'),
url(r'^pythonq/$', views.pythonq, name='pythonq'),
url(r'^pythonr/$', views.pythonr, name='pythonr'),
url(r'^mini/$', views.mini, name='mini'),
]
This is my view.py
from django.shortcuts import render
from .models import logininfo,CSTEST,CTEST,CPPTEST,JAVATEST,PYTHONTEST,result
from django.http import HttpResponse
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import cache_control
import datetime
def login(request):
if request.method=="POST":
user_name=request.POST.get("username")
sid=request.POST.get("sid")
password=request.POST.get("password")
article = logininfo()
article.user_name = user_name
article.sid = sid
article.password = password
article.save()
return render(request,'login.html')
def home(request):
if request.method=="POST":
sid=request.POST.get("sid")
password=request.POST.get("password")
request.session['sd'] = sid
user_obj=logininfo.objects.filter(sid=sid,password=password)
if user_obj.count()==0:
return HttpResponse("Sorry wrong password try again")
return render(request,'home.html')
def register(request):
return render(request,'register.html')
def javaq(request):
context = {
'query_results' : JAVATEST.objects.all()
}
return render(request, 'javaq.html',context)
def javar(request):
if request.method=="POST":
chosenOption = ''
correctAns = ''
c=0
x=1
for ans in JAVATEST.objects.all():
chosenOption=str(request.POST.get("java"+str(x)))
correctAns=str(ans.ANSWER)
if chosenOption==correctAns:
c=c+1
x=x+1
article = result()
article.sid = request.session['sd']
article.marks = c
article.subject = 'JAVA'
article.tdate = str(datetime.datetime.now())
article.save()
context = {
'query_results1' :c
}
return render(request, 'javar.html',context)

Add the #login_required decorator to your view function (the ones that render the pages that shouldn't appear to non logged in users).
You can have a broader idea about this decorator in this page.

You can use django built-in login-authentication on pages
#login_required(login_url='/url where you want user to redirect/')
def myview(request):
do something
return something #returns when user is logged in

Perhaps you should take a look at Django Stronghold.
Enable this in your settings, as per the instructions, and every view becomes private by default.
You can then decorate any functions which you want public access to like this:
#public
def register():
# Do something
This is probably the way to go for a beginner, as what you're doing just now (handling authentication logic in the home view) means you'll be repeating this for each separate view, and if you miss something, private parts of the app could end up public.

Related

Specifying view function in Django

I'm practicing in Django and I want to know how requests and view mechanisms work correct in Django.
I started an app called ghcrawler in my django project. I designed like it has to send responses that recevied from localhost/ghcrawler and localhost/ghcrawler/results
So this is the urls.py in ghcrawler/ app folder.
from django.urls import path, include
from .views import main_view, results_view
urlpatterns = [
path('', main_view.as_view() , name='ghcrawler'),
path('ghresults', results_view.as_view(), name='getresults')
]
localhost/grcrawler page works well as expected. I just want to wire the requests coming to localhost/ghcrawler/results to getresults() function in results_view class defined in views.py, however it doesn't even write the 'h1' to the console
ghcrawler/views.py:
from django.views.generic import TemplateView
from django.shortcuts import render
from django import forms
from django.http import HttpResponse
from .github_requester import search_user
class main_view(TemplateView):
template_name = 'ghcrawler.html'
# Handle the post request received from /ghcrawler/
def post(self, request, *args, **kwargs):
if request.method == 'POST':
user = search_user(request.POST.get("username", ""))
if user == None:
print("User not found.")
else:
print(user)
return HttpResponse("OK")
class results_view(TemplateView):
template_name = 'ghresults.html'
def getresults(self, request, *args, **kwargs):
print('h1')
Rather than localhost/ghcrawler/results you mapped localhost/ghcrawler/ghresults to your view.
the rigth code would be:
urlpatterns = [
path('', main_view.as_view() , name='ghcrawler'),
path('results', results_view.as_view(), name='ghresults')
]
the firs argument in pathis the actual path
the secont argumen is the view
the third argument name is optional and used for addressing your view independant of your path
class results_view(TemplateView):
template_name = 'ghresults.html'
def get(self, request, *args, **kwargs):
print('h1')

Reverse and HttpResponseRedirect don't work with DefaultRouter

I need to send back response with product details, so I use HttpResponseRedirect and reverse. It requires the app_name:name, so I tried something like below, but I get error:
django.urls.exceptions.NoReverseMatch: Reverse for 'product' not found. 'ProductViewSet' is not a valid view function or pattern name.
This is my view:
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def bump(request, pk):
product = get_object_or_404(Product, id=pk)
product.bumps.add(request.user)
return HttpResponseRedirect(reverse('products:product', args=[pk]))
This is my urls:
app_name = 'products'
router = DefaultRouter()
router.register(r'', ProductViewSet)
urlpatterns = [
path('', include(router.urls), name='product'),
]
What is wrong in this code? I use the correct app_name and name.
What is wrong in this code? I use the correct app_name and name.
The path you use does not link to a view: it is a path that contains a lot of subpaths, all generated by the DefaultRouter.
You are using a router, this means that it will create different paths that will each have a specific name. These are documented in the documentation for the DefaultRouter [drf-doc].
You thus can visit this with:
from django.shortcuts import redirect
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def bump(request, pk):
product = get_object_or_404(Product, pk=pk)
product.bumps.add(request.user)
return redirect('products:product-detail', pk)

Django "NoReverseMatch: Reverse for 'ads.views.AdListView' not found" while doing Test

I implemented some tests to check the status code of some pages, but this one with the reverse function throws me the error: django.urls.exceptions.NoReverseMatch: Reverse for 'ads.views.AdListView' not found. 'ads.views.AdListView' is not a valid view function or pattern name.
Reading the documentation and some answers on Stack Overflow I'm supposed to use either the view function name or the pattern name inside the parenthesis of the reverse function, but none of them seems to work.
Here's my code:
ads/tests/test_urls.py
from django.test import TestCase
from django.urls import reverse
class SimpleTests(TestCase):
def test_detail_view_url_by_name(self):
resp = self.client.get(reverse('ad_detail'))
# I've also tried: resp = self.client.get(reverse('ads/ad_detail'))
self.assertEqual(resp.status_code, 200)
...
ads\urls.py
from django.urls import path, reverse_lazy
from . import views
app_name='ads'
urlpatterns = [
path('', views.AdListView.as_view(), name='all'),
path('ad/<int:pk>', views.AdDetailView.as_view(), name='ad_detail'),
...
]
mysite/urls.py
from django.urls import path, include
urlpatterns = [
path('', include('home.urls')), # Change to ads.urls
path('ads/', include('ads.urls')),
...
]
ads/views.py
class AdDetailView(OwnerDetailView):
model = Ad
template_name = 'ads/ad_detail.html'
def get(self, request, pk) :
retrieved_ad = Ad.objects.get(id=pk)
comments = Comment.objects.filter(ad=retrieved_ad).order_by('-updated_at')
comment_form = CommentForm()
context = { 'ad' : retrieved_ad, 'comments': comments, 'comment_form': comment_form }
return render(request, self.template_name, context)
Any idea of what is causing the problem?
Since you use an app_name=… in your urls.py, you need to specify this as a namespace in the name of the view, so ads:ad_detail, and specify a primary key:
resp = self.client.get(reverse('ads:ad_detail', kwargs={'pk': 42}))
So here we visit the URL where 42 is used as value for the pk URL parameter.

Django redirect() doesn't redirect but rather refreshes the same page

view.py
#login_required(login_url='index', redirect_field_name=None)
def new_character(request):
if request.method == 'POST':
character_form = CharacterForm(request.POST)
if character_form.is_valid():
new_character = character_form.save(commit=False)
new_character.creator = request.user
new_character.save()
# If new_character has a primary key (pk) then it
# means it was saved to the database.
if new_character.pk:
# TODO: For some reason this doesn't work.
redirect('list_characters')
else:
character_form = CharacterForm()
return render(request, 'characters/new-character.html', {'character_form': character_form})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.list_characters, name='list_characters'),
path('new/', views.new_character, name='new_character'),
]
I checked and new_character.pk is coerced to True. However, the redirect doesn't happen and instead the same page is simply refreshed.
The issue here is that you are not returning the redirect, which results in the return render(request, 'characters/new-character.html'... being hit, changing from:
redirect('list_characters')
To:
return redirect('list_characters')
Should solve the issue

unable to redirect to some view in Django python

AoA,
I am trying to redirect to some view, but failed to do so.
here is the code
views.py
def logout(request):
c = {'username': 'Create Account', 'status': ''}
c.update(csrf(request))
response = render_to_response("home.html",c)
response.delete_cookie('id')
request.session['id'] = 'None'
return redirect('/home/')
def home(request):
#some code here
return render_to_response('blah blah')
urls.py
url(r'^home/$', 'contacts.views.home_Page'),
url(r'^logout/$', 'contacts.views.logout'),
the above code redirect me to -- let's suppose current URL(127.0.0.1/account)
it redirects me to (127.0.0.1/account/home) but i want to redirect to 127.0.0.1/home
how can I redirect to specific view ?
redirect(to[, permanent=False], *args, **kwargs) returns an HttpResponseRedirect to the appropriate URL for the arguments passed. You need to return the HttpResponseRedirect object in the view function.
BTW, you should try to avoid hardcoding urls in you code, instead you should use view names.
e.g:
urls.py:
url(r'^home/$', home, name='home_view')
...
view.py:
def logout(request):
...
redirect('home_view')
django provides a built-in logout that you should use:
from django.shortcuts import redirect
from django.contrib.auth import logout
def log_out(request):
logout(request)
return redirect('home')
Now 'home' can be many things; but the easiest way to make sure its pointing to the right place is to name your urls. So in your urls.py:
url(r'home/$', home, name='home')

Categories