Django SyntaxError: invalid syntax 'else' statement? - django

for god sake I can't understand why I'm getting this error, it looks to be simple stuff but I've made a lot of modifications now and don't know what exactly caused this:
(from Traceback):
File "C:\Users\Lucas Cyrne Ferreira\Desktop\django- tutorial\mysite\contas\urls.py", line 2, in <module>
from . import views
File "C:\Users\Lucas Cyrne Ferreira\Desktop\django-tutorial\mysite\contas\views.py", line 38
else:
^
SyntaxError: invalid syntax
from django.shortcuts import render, redirect, HttpResponse
from contas.forms import (
RegistrationForm,
EditPerfilForm,
)
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
def home(request):
return render(request, 'contas/home.html')
def register(request):
if request.method=='POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect(reverse('home:home'))
else:
form = RegistrationForm()
args = {'form':form}
return render(request, 'contas/reg_form.html', args)
def view_perfil(request):
args = {'user': request.user}
return render(request, 'contas/perfil.html', args)
def edit_perfil(request):
if request.method=='POST':
form = EditPerfilForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect(reverse('home:perfil')
else:
form = EditPerfilForm(instance=request.user)
args = {'form':form}
return render(request, 'contas/edit_perfil.html', args)
def trocar_password(request):
if request.method=='POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect(reverse('home:perfil')
else:
return redirect(reverse('home:trocar_password'))
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'contas/trocar_password.html', args)
My contas\urls.py:
from django.urls import path
from . import views
from django.contrib.auth.views import (
login,
logout,
PasswordResetView,
PasswordResetDoneView,
PasswordResetConfirmView,
PasswordResetCompleteView,
)
app_name = 'contas'
urlpatterns = [
path('', views.home, name='home'),
path('login/', login, {'template_name': 'contas/login.html'}, name='login'),
path('logout/', logout, {'template_name': 'contas/logout.html'}, name='logout'),
path('register/', views.register, name='register'),
path('perfil/', views.view_perfil, name='view_perfil'),
path('perfil/edit/', views.edit_perfil, name='edit_perfil'),
path('trocar-password/', views.trocar_password, name='trocar_password'),
path('reset-password/', PasswordResetView.as_view(), {'template_name': 'contas/reset_password.html', 'post_reset_redirect': 'contas:password_reset_done'},
name='reset_password'),
path('reset-password/done/', PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/',
PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset-password/complete/', PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
Please help me guys, I was in the middle of a namespace tutorial... now I'm stuck on this.

You've got a missing closing parenthesis in line 39:
return redirect(reverse('home:perfil') # missing )
I'd definitely recommend using a linter such as flake8 in your project and finding a plugin for whatever code editor or IDE you use. It will find errors like and save you a lot of grief in the long run.

Related

Django redirect another view from another app form

contact/views.py
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
def contactView(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(subject, message, from_email, ['admin#example.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
# return redirect('success')
return redirect('PostList') #another view from another app
return render(request, "contact.html", {'form': form})
# def successView(request):
# return HttpResponse('Success! Thank you for your message.')
contact/urls.py
from django.contrib import admin
from django.urls import path
from .views import contactView
urlpatterns = [
path('contact/', contactView, name='contact'),
# path('success/', successView, name='success'),
]
blog/views.py
from django.views import generic
from .models import Post, PostImage
# Create your views here.
class PostList(generic.ListView):
queryset = Post.objects.filter(status=1).order_by('-created_on')
template_name = 'index.html'
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet of all the books
# context['image_list'] = PostImage.objects.all()
# context['image_list'] = self.get_object().postimage_set.all()
context['image_list'] = PostImage.objects.filter(post__slug=self.kwargs.get('slug'))
return context
blog/urls.py
from . import views
from django.urls import path
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]
I need the following in the SIMPLEST DRY manner possible; how do I write this redirect inside contact/views.py?
return redirect('PostList') #another view from another app
PostList is a class-based view from another app called blog. It is the homepage essentially.
for reference..
https://ordinarycoders.com/blog/article/django-messages-framework
In your project folder (eg, my_project/my_project) you should have a urls.py with something like this
path("admin/", admin.site.urls),
path("", include("blog.urls")),
path("", include("contact.urls"))
This allows django to look through all url files in the order listed. So long as all your url names and patterns are unique, then your view should be able to simply do
from django.shortcuts import redirect
from django.urls import reverse
return redirect(reverse('home'))
'home' being the name value of the ListView.
(NB: if you have various applevel urls.py files with path(''... django will take the first one it hits)

django.core.exceptions.ImproperlyConfigured error

Here is the error message:
django.core.exceptions.ImproperlyConfigured:
The included URLconf '<module 'basicsiteApp' from '/Users/msa/trydjango/basicsite/basicsiteApp/__init__.py'>'
does not appear to have any patterns in it.
If you see valid patterns in the file then the issue is probably
caused by a circular import.
I don't have anything written in init.py because I don't know what I need to write in it so it can work.
Below is what I have in views.py:
from django.shortcuts import render
from .forms import SignUpForm
from django.contrib import messages
def signup(request):
if request.method == 'POST'
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Account Created')
return render(request, 'signup.html')
else:
form = SignUpForm()
render(request, 'signup.html')
Basicsite/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('basicsiteApp')),
path('admin/', admin.site.urls)
]
basicsiteApp/urls.py:
from django.urls import path
from . import views
app_name = 'basicsiteApp'
urlpatterns = [
path('', views.signup, name='signup')
]
I know it comes late, but if someone (like me) faces the same problem:
In your "Basicsite/urls.py"
path('', include('basicsiteApp')),
it should be
path('', include('basicsiteApp.urls')),
implying django to use the basicsiteApp/urls.py file instead of basicsiteApp/init.py

redirect, can't leave login page

having trouble with this tutorial. in my views.py I have this function for login, in views.py:
def login_view(request, *args, **kwargs):
form = AuthenticationForm(request, data=request.POST or None)
if form.is_valid():
user_ = form.get_user()
login(request, user_)
**return redirect("/")**
context = {
"form": form,
"btn_label": "Login",
"title": "Login"
}
return render(request, "accounts/auth.html", context)
however when i try to change the redirect , i only get errors, what should I put in the redirect? i've tried everything like
return redirect("/tweets/list.html")
and
return redirect("public/index.html")
both are locations of file names in the templates folder. I am getting the error, "Page not found (404)". The only address that did redirect was when I put https://www.google.com/
in accounts/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
# Create your views here.
# Function based views to Class Based Views
def login_view(request, *args, **kwargs):
form = AuthenticationForm(request, data=request.POST or None)
if form.is_valid():
user_ = form.get_user()
login(request, user_)
return redirect('')
context = {
"form": form,
"btn_label": "Login",
"title": "Login"
}
return render(request, "accounts/auth.html", context)
def logout_view(request, *args, **kwargs):
if request.method == "POST":
logout(request)
return redirect("/login")
context = {
"form": None,
"description": "Are you sure you want to logout?",
"btn_label": "Click to Confirm",
"title": "Logout"
}
return render(request, "accounts/auth.html", context)
def register_view(request, *args, **kwargs):
form = UserCreationForm(request.POST or None)
if form.is_valid():
user = form.save(commit=True)
user.set_password(form.cleaned_data.get("password1"))
# send a confirmation email to verify their account
login(request, user)
return redirect("/")
context = {
"form": form,
"btn_label": "Register",
"title": "Register"
}
return render(request, "accounts/auth.html", context)
here is urls.py:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, re_path, include # url()
from django.views.generic import TemplateView
from accounts.views import (
login_view,
logout_view,
register_view,
)
from tweets.views import (
home_view,
tweets_list_view,
tweets_detail_view,
)
urlpatterns = [
path('', home_view),
path('admin/', admin.site.urls),
path('global/', tweets_list_view),
path('login/', login_view),
path('logout/', logout_view),
path('register/', register_view),
path('<int:tweet_id>', tweets_detail_view),
re_path(r'profiles?/', include('profiles.urls')),
path('api/tweets/', include('tweets.api.urls')),
re_path(r'api/profiles?/', include('profiles.api.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
thnx
Redirect should take a valid path to an url defined in urls.Py, not a file in templates/some/urls.html.
I would suggest not to used "hard coded urls" though, but instead using the view name and parameters such as return redirect('some-view-name', foo='bar')
i solved the error by looking at urls.py, looking into url patterns, picking
path('global/', tweets_list_view),
and dropping '/global/' into return redirect("/") so that line looks like:
return redirect("/global/")

How to make custom 404 page for the Detail view with <int:pk>, if the instance not found?

so the error is Page not found(404) when I am requesting the instance that does not exist. I would like to customize the 404 page, instead of displaying the general error.
Here is my new_wiki/urls
from django.urls import path
from . import views
from .views import IndexView, InstanceView, AddPostView, EditPost
urlpatterns = [
# path('', views.index, name="index")
path('', IndexView.as_view(), name="index"),
path('instance/<int:pk>', InstanceView.as_view(), name="instance"),
path('create_post/', AddPostView.as_view(), name="create_post"),
path('instance/edit/<int:pk>', EditPost.as_view(), name="edit_post")
]
And my InstanceView class
class InstanceView(DetailView):
model = Post
template_name = 'new_wiki/instance.html'
I have tried to use the solution from Django documentation:
def detail(request, post_id):
try:
p = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
raise Http404("Poll does not exist")
return render(request, 'new_wiki/instance.html', {'post': p})
but it is still returning the same 404 page. Thank you
You can just render a page with a 404 status:
def detail(request, post_id):
try:
p = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
return render(request, 'new_wiki/404error.html', status=404)
return render(request, 'new_wiki/instance.html', {'post': p})
If you want to specify a custom 404 page in general, you specify the handler404 [Django-doc] in the urls.py:
from django.urls import path
from . import views
from .views import IndexView, InstanceView, AddPostView, EditPost
urlpatterns = [
# path('', views.index, name="index")
path('', IndexView.as_view(), name="index"),
path('instance/<int:pk>', InstanceView.as_view(), name="instance"),
path('create_post/', AddPostView.as_view(), name="create_post"),
path('instance/edit/<int:pk>', EditPost.as_view(), name="edit_post")
]
handler404 = views.handler404
In the view you can then analyze the exception parameter and return a specific
# app/views.py
from django.http import HttpResponseNotFound
def handler404(request, exception):
data = exception.args
if data:
return HttpResponseNotFound(data[0])
return HttpResponseNotFound('some text')
This then works if you set the DEBUG setting [Django-doc] to False:
# settings.py
DEBUG = False
In that case the handler will be invoked when you raise a Http404.
Please use get_object_or_404 method
from django.shortcuts import get_object_or_404
def detail(request, post_id):
p = get_object_or_404(Post,pk=post_id)
return render(request, 'new_wiki/instance.html', {'post': p})
Please check this is working.

views must be a callable or a list\tuple in case of include [duplicate]

This question already has answers here:
Django URLs TypeError: view must be a callable or a list/tuple in the case of include()
(6 answers)
Closed 5 years ago.
Django==1.10.5
Login.
I have made login form, then write these codes and wanted to run the server
Urls.py:
urlpatterns = [
#previous login view
#url(r'^login/$', views.user_login, name='login'),
#login/logout urls
url(r'^$', views.dashboard, name='dashboard'),
url(r'^login/$', 'login', name='login'),
url(r'^logout/$', 'django.contrib.auth.views.logout', name='logout'),
url(r'^logout-thenlogin/$','django.contrib.auth.views.logout_then_login',
name='logout_then_login'),
]
Views.py:
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from .forms import LoginForm
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd['username'], password=cd['password'])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
form = LoginForm()
return render(request, 'account/login.html', {'form': form})
#login_required
def dashboard(request):
return render(request, 'account/dashboard.html', {'section': 'dashboard'})
When i wanted to runserver- i got this message:
Views must be a callable or a list\tuple in case of include
Django 1.10+ no longer allows you to specify views as a string (e.g. 'myapp.views.home') in your URL patterns.
The solution is to update your urls.py to include the view callable. This means that you have to import the view in your urls.py. If your URL patterns don't have names, then now is a good time to add one, because reversing with the dotted python path no longer works.
urlpatterns = [
#previous login view
#url(r'^login/$', views.user_login, name='login'),
#login/logout urls
url(r'^$', views.dashboard, name='dashboard'),
url(r'^login/$', your_app_name.views.user_login, name='login'),
url(r'^logout/$', django.contrib.auth.views.logout, name='logout'),
url(r'^logout-thenlogin/$', django.contrib.auth.views.logout_then_login,
name='logout_then_login'),
]