User matching query does not exist - django - django

I have a page which shows the user and their about. And in that, there's a link to update their about. But when I open that link it shows me with this error:
DoesNotExist at /profile/user/update_about/
User matching query does not exist.
And the traceback hightlights this line, which from the profile method in the views:
13. user = User.objects.get(username=unquote(user_name))
However this error does not occur when I load the profile method. It occurs only on the update_profile method in the views.
views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from urllib import unquote
from django.contrib.auth.models import User
from models import About
from forms import AboutForm
# Create your views here.
def profile(request, user_name):
user = User.objects.get(username=unquote(user_name))
about = About.objects.get_or_create(user=user)
about = about[0]
return render(request, 'user_profile.html', {
'user':user,
'about_user':about
})
def update_about(request, user_name):
user = User.objects.get(username=unquote(user_name))
if request.method == 'POST':
form = AboutForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
about = About.objects.get(user=user)
form = AboutForm(initial={'dob':about.dob})
return render(request, 'update_about.html',{
'form':form
})
urls.py
urlpatterns = patterns('',
# Examples:
url(r'(?P<user_name>[\w#%.]+)/$', 'user_related.views.profile', name='profile'),
url(r'(?P<user_name>[\w#%.]+)/update_about/$', 'user_related.views.update_about', name='update_about'),
What is causing this? Your help will be very much appreciated. Thank you.

You forgot to add the caret sign (^) at the first position of regex. So the first regex matched "update_about/" part of the url.
Fixed code:
url(r'^(?P<user_name>[\w#%.]+)/$', 'user_related.views.profile', name='profile'),
url(r'^(?P<user_name>[\w#%.]+)/update_about/$', 'user_related.views.update_about', name='update_about'),

Related

AttributeError (Django)

I am getting an error:
'FeedBackForm' object has no attribute 'FeedBackForm'
I have tried all troubleshooting steps but no luck. It will be much appreciable if anyone can help.
form.py
from django import forms
class FeedBackForm(forms.Form):
name=forms.CharField()
Ldap_id=forms.CharField()
email=forms.EmailField()
company_name=forms.CharField()
feedback=forms.CharField(widget=forms.Textarea)
views.py
from django.shortcuts import render
from testapp import forms
# Create your views here.
def feedback_view(request):
form = forms.FeedBackForm()
# As here we are sending details to register.html and in html file
# we have not mentioned action where this file will go
# so it will come back here in views.py file only. :)
if request.method == 'POST':
form1 = form.FeedBackForm(request.POST)
if form1.is_valid():
print("Form Validation sucess and printing feedback info")
# Now to capture data we will use cleaned_data===>cleaned_data==>{name:value}
print('Name of editor:', form1.cleaned_data['name'])
print('LDAP of editor:', form1.cleaned_data['Ldap_id'])
print('EmailId:', form1.cleaned_data['email'])
print('Company:', form1.cleaned_data['company'])
print('Feedback provided:', form1.cleaned_data['feedback'])
# Note this above if form.is_valid(): will start working
# only when we will submit form otherwise it will not start.
my_dict = {'form': form}
return render(request, 'testapp/register.html', context=my_dict)
urls.py
from django.contrib import admin
from django.urls import path
from testapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('register/',views.feedback_view),
]
You can not use form.FeedbackForm, since you assigned form as FeedbackForm object. You should use forms.FeedbackForm:
from django.shortcuts import render
from testapp import forms
def feedback_view(request):
form = forms.FeedBackForm()
# As here we are sending details to register.html
# and in html file we have not mentioned action where
# this file will go so it will come back here in views.py
# file only. :)
if request.method == 'POST':
form1 = forms.FeedBackForm(request.POST)
if form1.is_valid():
print("Form Validation sucess and printing feedback info")
# Now to capture data we will use cleaned_data===>cleaned_data==>{name:value}
print('Name of editor:', form1.cleaned_data['name'])
print('LDAP of editor:', form1.cleaned_data['Ldap_id'])
print('EmailId:', form1.cleaned_data['email'])
print('Company:', form1.cleaned_data['company'])
print('Feedback provided:', form1.cleaned_data['feedback'])
# Note this above if form.is_valid(): will start working only
# when we'll submit form otherwise it will not start.
my_dict = {'form': form}
return render(request, 'testapp/register.html', context=my_dict)

django redirect after form submission not working

new to django
so this one probably has a very simple answer but i cannot for the life of me find the specific solution to this. I am simply trying to redirect to a new URL after a form submission with a FileField.
I can navigate to the URL separately and it works fine.
The file uploads correctly so I know it is validated correctly.
But the redirect returns the following error:
Reverse for 'success' not found. 'success' is not a valid view function or pattern name.
I have tried a bunch of different naming conventions, but none has worked. It looks to me like I have setup the URL and passed it correctly.
Would really appreciate some help with this. The simplest problems are the most frustrating!
Here are the views.
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .forms import InvestmentReportForm
def upload(request):
if request.method == 'POST':
form = InvestmentReportForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('success')
else:
form = InvestmentReportForm()
return render(request, 'app/upload.html', {'form': form})
def success(request):
return HttpResponse("File successfully uploaded")
And my urls.py:
app_name = 'app'
urlpatterns = [
path('', views.index, name='index'),
path('upload/', views.upload, name='upload'),
path('success/', views.success, name='success'),
path('performance/', views.performance, name='performance'),
]
The answer was simple as I suspected. For others, if you use a namespace for a set of url patterns, you have to refer to that namespace when calling those urls. For this example:
return redirect('app:success')
def upload(request):
if request.method == 'POST':
form = InvestmentReportForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('success/')
else:
form = InvestmentReportForm()
return render(request, 'app/upload.html', {'form': form})

Django. Сheck activation code

UPDATE!
The activation code is stored in the database, but I can not call it as a function of activation
Gives an error message:
TypeError at /account/activation/18d2ecbee1fd15440bbcfdf942c071a2f5b8d0ff/
activation() got an unexpected keyword argument 'activation_key'
forms.py
from django import forms
from django.contrib.auth.models import User
class EmailForm(forms.Form):
email = forms.EmailField(widget=forms.EmailInput(
attrs={'class': 'form-control input-lg',
'placeholder': 'Ваш E-mail'}))
views.py
import datetime
import hashlib
import random
from django.conf import settings
from django.contrib.auth import authenticate, logout, login
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from django.http import HttpResponseRedirect, HttpResponse
from django.http import Http404
from django.shortcuts import render
from forms import *
from models import *
def register(request):
if request.method == "POST":
form = EmailForm(request.POST)
if form.is_valid():
form_email = form.cleaned_data['email']
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
activation_key = hashlib.sha1(salt+form_email).hexdigest()
key_expires = datetime.datetime.today() + datetime.timedelta(2)
subject = 'Activation your e-mail'
from_email = settings.EMAIL_HOST_USER
to_email = [form_email]
message_email = "Hi, i'm link activate e-mail! \
http://127.0.0.1:8000/account/activation/%s" % activation_key
send_mail(subject,
message_email,
from_email,
to_email,
fail_silently=True)
code = ActivationEmail.objects.create(activation_key=activation_key)
code.save()
return render(request, 'registration/activate.html', locals())
else:
form = EmailForm()
return render(request, 'registration/register.html', locals())
def activation(request, code):
try:
active = ActivationEmail.objects.get(activation_key=code)
except ActivationEmail.DoesNotExist:
active = None
active.validated = True
if not active:
raise Http404
print "USER WAS HERE?!"
return HttpResponseRedirect('/account/wizard/')
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^register/', views.register, name='registration'),
url(r'^activation/(?P<activation_key>\w+)/', views.activation, name='activation'),
url(r'^login/$', views.user_login, name='login'),
url(r'^logout/$', views.user_logout, name='logout'),
Just can not figure out how to do next; (
You will need to
1- You will need to create a new table to store the activation keys, such that you can create a new entry before sending the email
2.- On the user clicking the activation link, that link should be sufficient for you to find the record you created before sending the email
3.- If everything matches, then set a user.is_active type thing on your user model.
But all that said, you are reinventing the wheel here. There are several top notch packages you can use with this and more. I would recommend django-allauth with also give you social login support (e.g. facebook). If you just want the activation portion, there is an older package called django-registration. There are a few others if you search around, but the point is you don't need to implement this (and you probably don't want to mess around with registration if you are not an expert)

Django retrieve data from db to complete a url pattern

I know this is an easy question, I am just not getting something...so thank you for your patience and advice.
I have a view that asks a user to register to use our app. The data he/she submits is stored in a database and he is sent off to another page to set up the application:
#views.py
def regPage(request, id=None):
form = RegForm(request.POST or None,
instance=id and UserRegistration.objects.get(id=id))
# Save new/edited pick
if request.method == 'POST' and form.is_valid():
form.save()
return HttpResponseRedirect('/dev/leaguepage/')
user_info = UserRegistration.objects.all()
context = {
'form':form,
'user_info' :user_info,
}
return render(request, 'regpage.html', context)
Rather than sending ALL users to the same page '/dev/leaguepage/', I need to send each user to his own page based on the PK in the database like: '/dev/PrimaryKey/' I am not sure how to make this happen either on the views file or in the URLs.py file:
#urls.py
from django.conf.urls.defaults import patterns, include, url
from acme.dc_django import views
urlpatterns = patterns('',
url(r'^leaguepage/$','acme.dc_django.views.leaguePage'),
url(r'^$', 'acme.dc_django.views.regPage'),
)
Thank you for your help!
dp
Updated code:
#url
url(r'^user/(?P<id>\d+)/$','acme.dc_django.views.leaguePage', name="league_page"),
#view
def regPage(request, id):
form = RegForm(request.POST)
# Save new/edited pick
if request.method == 'POST' and form.is_valid():
form.save()
return HttpResponseRedirect(reverse('league_page', kwargs={'id' :id}))
#return HttpResponseRedirect('/dev/leaguepage/')
user_info = UserRegistration.objects.all()
context = {
'form':form,
'user_info' :user_info,
}
return render(request, 'regpage.html', context)
You can do a reverse lookup on your leaguePage to do your redirect, passing in the values you need to resolve the pattern. You'll need to add a name to the URL pattern you want to reverse, but basically the syntax is:
return HttpResponseRedirect(reverse('my_detail', args=(), kwargs={'id' : id}))
Example URL pattern and view:
urlpatterns = patterns('my_app.views',
url(r'^my-pattern/(?P<id>\d+)/$', 'my_action', name='my_detail'),
)
def my_action(request, id):
#do something
Hope that helps you out.

Login URL using authentication information in Django

I'm working on a platform for online labs registration for my university.
Login View [project views.py]
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib import auth
def index(request):
return render_to_response('index.html', {}, context_instance = RequestContext(request))
def login(request):
if request.method == "POST":
post = request.POST.copy()
if post.has_key('username') and post.has_key('password'):
usr = post['username']
pwd = post['password']
user = auth.authenticate(username=usr, password=pwd)
if user is not None and user.is_active:
auth.login(request, user)
if user.get_profile().is_teacher:
return HttpResponseRedirect('/teachers/'+user.username+'/')
else:
return HttpResponseRedirect('/students/'+user.username+'/')
else:
return render_to_response('index.html', {'msg': 'You don\'t belong here.'}, context_instance = RequestContext(request)
return render_to_response('login.html', {}, context_instance = RequestContext(request))
def logout(request):
auth.logout(request)
return render_to_response('index.html', {}, context_instance = RequestContext(request))
URLS
#========== PROJECT URLS ==========#
urlpatterns = patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),
(r'^admin/', include(admin.site.urls)),
(r'^teachers/', include('diogenis.teachers.urls')),
(r'^students/', include('diogenis.students.urls')),
(r'^login/', login),
(r'^logout/', logout),
(r'^$', index),
)
#========== TEACHERS APP URLS ==========#
urlpatterns = patterns('',
(r'^(?P<username>\w{0,50})/', labs),
)
The login view basically checks whether the logged in user is_teacher [UserProfile attribute via get_profile()] and redirects the user to his profile.
Labs View [teachers app views.py]
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth.models import User
from accounts.models import *
from labs.models import *
def user_is_teacher(user):
return user.is_authenticated() and user.get_profile().is_teacher
#user_passes_test(user_is_teacher, login_url="/login/")
def labs(request, username):
q1 = User.objects.get(username=username)
q2 = u'%s %s' % (q1.last_name, q1.first_name)
q2 = Teacher.objects.get(name=q2)
results = TeacherToLab.objects.filter(teacher=q2)
return render_to_response('teachers/labs.html', {'results': results}, context_instance = RequestContext(request))
I'm using #user_passes_test decorator for checking whether the authenticated user has the permission to use this view [labs view].
The problem I'm having with the current logic is that once Django authenticates a teacher user he has access to all teachers profiles basically by typing the teachers username in the url.
Once a teacher finds a co-worker's username he has direct access to his data.
Any suggestions would be much appreciated.
A simple way would be to modify the view to add an extra check:
#user_passes_test(user_is_teacher, login_url="/login/")
def labs(request, username):
if username != request.user.username:
return HttpResponseNotAllowed()
... and so on ...
Assuming you have a variable called 'teacher' that represents the profile of the teacher whose profile you're viewing, just do something like this early in the view:
if request.user.get_profile() != teacher:
..redirect, throw 404, whatever you fancy
Just a short hint.
...
user = request.user
enrollment = get_object_or_404(Enrollment, id=enrollment_id)
profile = get_object_or_404(Profile, user=user)
if not (enrollment.profile == profile or user.is_staff):
raise Http404
...
enrollment.delete()
We used such if statements to determine, whether the actual user and the action he requested match. In the example above, only the profile who create an enrollment is allowed to delete it (or someone with staff priviledges).