Django retrieve data from db to complete a url pattern - django

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.

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})

Redirect to next URL in django FormView

I am using Django 1.7 with Python 3.4. I have a scenario where I wish the users to be redirected to another view, as defined in the next GET parameter, after they login. But with my current setup, they always get redirected to the home page. I was hoping there is a way to do this in the get_success_url of the FormView class.
Below is my code
The next parameter in the URL
http://localhost:8000/login/?next=/ads/new
views.py
from django.views.generic.edit import FormView
class LoginView(FormView):
template_name = 'users/login.html'
form_class = LoginForm
def get_success_url(self):
return reverse('home')
def form_valid(self, form):
form.user.backend = 'django.contrib.auth.backends.ModelBackend'
login(self.request, form.user)
messages.info(self.request, 'Login successful')
return super(LoginView, self).form_valid(form)
urls.py
url(r'^login/', LoginView.as_view(), name='login'),
url(r'^new$', 'apps.adverts.views.add_new_advert', name='new_advert'), # URL to use after login, in next param
With the above setup, how do I redirect to the next URL if it is defined, apart from the home page?
Include the data as GET parameters in your success url.
def get_success_url(self):
# find your next url here
next_url = self.request.POST.get('next',None) # here method should be GET or POST.
if next_url:
return "%s" % (next_url) # you can include some query strings as well
else :
return reverse('home') # what url you wish to return
Hope this will work for you.

Use Django sessions in URL

I currently am using Django to have users enter information via a form, and the data is then saved as a session. I then use this session to call the entered data in other views. I was wondering if it is possible to use this entered data stored in these sessions in my urls?
def search(request):
result = {}
context = RequestContext(request)
t = request.session.get("tick")
if request.method == 'POST':
search = Search(data=request.POST)
if search.is_valid():
ticker = search.cleaned_data['search']
request.session["tick"] = ticker
else:
print search.errors
else:
search = Search()
return render_to_response('ui/search.html', {"result":result}, context)
and here is my corresponding urls.py:
url(r'^search/$', views.search, name='search'),
Is there any way I can use the session that is saved as 't = request.session.get("tick")' in my urls so I could get the urls to correspond with the data the user entered? For example if the user entered, 'hello' then my urls would show /search/hello.
Thanks.
Yes, you can do it like this:
urls.py
url(r'^search/$', views.search, name='search'),
url(r'^search/(?P<query>.+)/$', views.search, name='search'),
views.py
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
def search(request, query=None):
result = {}
context = RequestContext(request)
if request.method == 'POST':
search = Search(data=request.POST)
if search.is_valid():
ticker = search.cleaned_data['search']
return HttpResponseRedirect(reverse('search', kwargs={'query': ticker}))
else:
print search.errors
else:
search = Search()
return render_to_response('ui/search.html', {"result":result}, context)

Redirect / return to same (previous) page in Django?

What are the options when you want to return the user to the same page in Django and what are the pros/cons of each?
Methods I know:
HTTP_REFERER
GET parameter containing the previous URL
Session data to store the previous URL
Are there any other?
One of the way is using HTTP_REFERER header like as below:
from django.http import HttpResponseRedirect
def someview(request):
...
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Not sure of cons of this!
100% working Example
For Class Based View and Function:
from django.http import HttpResponseRedirect
...
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
or
from django.http import HttpResponseRedirect
...
return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
Example -
class TaskNotificationReadAllView(generic.View):
def get(self, request, *args, **kwargs):
TaskNotification.objects.filter(assigned_to=request.user).update(read=True)
print(request.META.get('HTTP_REFERER'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
While the question and answer is old, I think it's lacking a few options. I have not find any cons with the methods, I would be happy to know if there are any?
request.path_info
request.get_full_path()
request.build_absolute_uri()
from django.shortcuts import redirect
redirect(request.path_info) # No query parameters
redirect(request.build_absolute_uri()) # Keeps query parameters
redirect(request.get_full_path()) # Keeps query parameters
In django view suppose you are not logged in but click on some content that content trigger some url like /board/2/new_topic then #login_required will redirect you to login page with this url
http://localhost:8000/signin/?next=/boards/2/new_topic/
so our aim is redirect to http://localhost:8000/boards/2/new_topic/ page after successful login so one line we will have to add
if 'next' in request.GET:
return redirect(request.GET['next'])
then if it next is there then it will redirect according to that other normal redirect .
Views.py :
def signin(request):
if request.method == "POST":
user_login_form = UserLoginForm(request.POST)
email = request.POST['email']
password = request.POST['password']
user = authenticate(request, email=email, password=password)
if user and user.is_active:
login(request, user)
if 'next' in request.GET:
return redirect(request.GET['next'])
else:
return redirect('home')
else:
return render(request, 'signin.html', context={'form': user_login_form})
else:
user_login_form = UserLoginForm()
return render(request, 'signin.html', context={'form': user_login_form})