I'm a newbie. And I just started writing a django project. It is called the iRayProject and consists of two applications iRay_user_authentication and iRay_working_with_notes:
project structure here
iRay_user_authentication - this is a standard django app for registration
Here is his urls.py
from django.urls import path
from .views import login_user, registration
urlpatterns = [
path('', login_user, name='login_user'),
path('registration', registration, name='registration'),
]
In views.py registered user using redirect I want to send to the second application of the project
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
from django.db import IntegrityError
from django.contrib.auth import login, logout, authenticate
from ..iRay_working_with_notes.views import list_notes
def login_user(request):
if request.method == 'GET':
return render(request, 'iRay_user_authentication/login.html', {'form': AuthenticationForm})
def registration(request):
if request.method == 'GET':
return render(request, 'iRay_user_authentication/registration.html', {'form': UserCreationForm})
else:
if '_guest' in request.POST:
pass
else:
if request.POST['password1'] == request.POST['password2']:
try:
user = User.objects.create_user(request.POST['username'], password=request.POST['password1'])
user.save()
login(request, user)
return redirect(list_notes)
except IntegrityError:
return render(request, 'iRay_user_authentication/registration.html', {'form': UserCreationForm,
'error': 'name is busy '
})
else:
return render(request, 'todo_app/registration.html', {'form': UserCreationForm,
'error': 'passwords not math'})
But when trying to import a function from the second views.py
from django.shortcuts import render
def list_notes(request):
return render(request, 'iRay_working_with_notes/list_notes.html')
I get an error:
ImportError: attempted relative import beyond top-level package
And I found a lot of theoretical information about why this error occurs.
But I still couldn 't figure out if there is an easy way for relative or absolute import , or I just didn 't structure my project correctly ??
import is wrong
from ..iRay_working_with_notes.views import list_notes
should be
from iRay_working_with_notes.views import list_notes
redirect needs view name from the urls-pattern:
redirect('name-of-my-view-pattern')
So please create a url-pattern entry for the list_notes view and give the pattern name as parameter to the redirect.
Why? because a redirect is telling the browser on the client side to load the target redirect page, so it needs an url (that is generated by django via the url-pattern), as the target page will be called from the browser.
Technically of course you can import a view and call it from another module directly as it is just a python function - but that is not a http redirect (and would not change the url in the browser to the redirected page) and additionally that is not really the idea of the django request/response architecture.
Related
I have created a blog with Django and whenever a user logs in, the URL redirects to the homepage and displays a success message. This is fine, however, whenever a login is required to view a certain page, Django redirects to the login page and attaches "?next=" to the end of the URL to redirect back to the previous page. The problem is that after the user logs in, the "next" URL is not executed and Django redirects to the homepage and displays the success message? Is there a way to disable this redirect whenever there is a "next" URL?
views.py
from django.urls import reverse
from django.contrib import messages
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.utils.safestring import mark_safe
from .forms import UserLoginForm
def login_view(request):
if request.method == 'POST':
form = UserLoginForm(data=request.POST)
if form.is_valid():
student = form.get_user()
login(request, user)
create_url = reverse('post-create')
messages.success(request, mark_safe(f'You are now logged in. Do you want to create a post?'))
return redirect('home')
else:
form = UserLoginForm()
return render(request, 'users/login.html', {'form': form, 'title': 'Log in'})
You can get this next url from request.GET and default to your homepage if it's not there
return redirect(request.GET.get('next', 'home'))
This way, if ?next=... is in the query parameters it will be used as the redirect path, if it's not then you will redirect to 'home'
Pease help use csrf token in django 1.11
in view.py i use follow code:
from django.shortcuts import render_to_response, redirect
from django.contrib import auth
from django.views.decorators.csrf import csrf
def login(request):
args = {}
args.update(csrf(request))
if request.POST:
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('/')
else:
args['login_error'] = 'Пользователь не найден';
return render_to_response('login.html', args)
else:
return render_to_response('login.html', args)
but console display follow error message:
File "/home/kalinin/django/login/views.py", line 3, in from
django.views.decorators.csrf import csrf ImportError: cannot import
name 'csrf'
in django 1.8 i use similar code, but import csrf:
from django.core.context_processors import csrf
and applications is running without problems
Please help run my application for django 1.11
In Django 1.8 the template context processor was moved to django.template.context_processors.csrf, so the import would be:
from django.template.context_processors import csrf
However, you don't need to import it at all. Stop using render_to_response, it's obsolete. Use the render shortcut instead.
from django.shortcuts import render
return render(request, 'login.html', args)
When you use the render shortcut, then you don't need to worry about the csrf token in the view, and you can remove this line.
args.update(csrf(request))
Here is my code that I believe pertains to this situation. I'm sorry, I'm new to django.
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import SearchForm
def result_one(request):
return render(request, "testresult.html", {})
def get_results(request):
if request.method == 'POST':
form = SearchForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/result/')
else:
form = SearchForm()
return render(request, 'index.html', {'form': form})
urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^search/$', "search.views.get_results"),
url(r'^result/$', "search.views.result_one"),
]
forms.py
from django import forms
class SearchForm(forms.Form):
client_group_number=forms.IntegerField(label='Group Number', widget=forms.TextInput(attrs={'placeholder': 'Group Number'}))
From my understanding, what I believe should happen is that an input will be put into a html page. When the user hits submit, the input gets saved into forms.py as data. This data gets manipulated in views.py which gets displayed in a different html page. (I hope this is correct)
What I want it to do is take in an input for client_group_number(in forms.py) from index.html(for example: 123), that can be accessed in views.py and displayed in another html template that I have called testresult.html, which would display Group Number = 123 (the 123 coming from either the forms.py or views.py).
This might be a very simple thing to accomplish and I apologize if it is, but I can't seem to find what I need on the internet.
Django validate the form input data in the cleaned_data dictionary. You would need to pass this to the new template either as arguments in the redirect or using session. Here is one simple example to give you an idea, there are probably better ways.
if form.is_valid():
group_number = form.cleaned_data["client_group_number"]
HttpResponseRedirect("/result/?group_number=" + group_number)
Hello I am trying to setup stripe payment for an e_commerc django application, and I have a problem whit displaying stripeToken, when I try to pay whit the stripe test credit card.
This is my views.py, where am I defining mine stripe payment:
from django.conf import settings
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
import stripe
# Create your views here.
#login_required
def checkout(request):
if request.method == 'POST':
print request.POST
user = request.user
context = {}
tempalte = 'checkout.html'
return render(request, tempalte, context)
When I use test credit card it will display only this
<QueryDict: {u'csrfmiddlewaretoken': [u'NP0q3qvVZs2C0dB2yEiSzmMuNMBS9jvD']}>, whitout stripeToken.
Can you tell me what am I mistaking here?
Thank you.
This just happened to one of my sites and I have no idea what caused it.
This happens for any URL that is served by mod_wsgi for a particular application, which used to work fine.
Syntax errors in settings.py cause HTTP 500.
Syntax errors in urls.py don't influence anything—seems like this file is never loaded.
What is there to check?
The culprit was this line:
from django.contrib.auth.forms import AuthenticationForm
in middleware.py.
Moving the import into the function that uses AuthenticationForm solved the problem:
from django.http import HttpResponseRedirect
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import login
#from django.contrib.auth.forms import AuthenticationForm <-- THE LINE WAS HERE
class LoginFormMiddleware(object):
def process_request(self, request):
if request.method == 'POST' and 'is_top_login_form' in request.POST:
from django.contrib.auth.forms import AuthenticationForm # <-- MOVED HERE
form = AuthenticationForm(data=request.POST)
is_valid = form.is_valid()
if is_valid:
login(request, form.get_user())
program = request.user.get_profile().first_intern.program
NavigationMiddleware.set_program(request, program)
return HttpResponseRedirect('%s?quick' % program.get_absolute_url())
else:
messages.error(request, request.POST['username'], extra_tags='login')
return HttpResponseRedirect(request.get_full_path())
I still have no idea why the code used to work, why it suddenly broke and why doing this solved the problem.
There has to be some magick in Python, after all.