How can I receive GET/POST value beside TemplateView class - python

I'm leaning Python to develop a website. I use Django framework to develop. To create a VIEW using django.views.generic.base.TemplateView.
So I wanna to get value 'user_name' and 'mail' from URL, but don't know how to do that! I cannot import request within this view.
Here is Views.py:
from django.views.generic.base import TemplateView
class MainView(TemplateView):
template_name = 'guestbook/main_page_1.html'
def get_context_data(self, **kwargs):
#I wanna to get value 'user_name' and 'mail' from URL...
name = request.GET.get("user_name") #temp
email = request.GET.get("mail") #temp
context = super(MainView, self).get_context_data(**kwargs)
context['var1'] = name
context['var2'] = email
return context
Here is Urls.py:
from django.conf.urls import patterns, url
from guestbook.views import MainView
urlpatterns = patterns('',
url(r'^$', MainView.as_view(), name='main'),
)
Anybody can help me to do this!
Thanks all!

Request is available in get_context_data() as self.request:
def get_context_data(self, **kwargs):
name = self.request.GET.get("user_name")
email = self.request.GET.get("mail")
...

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 error: 404 Page not found on get method

I am trying to get serialized data from endpoint localhost:8000/v1/test/uuid, but hitting a 404 error - what is wrong with below?
views.py
from uuid in response, get site object
class Test(APIView):
def get(self, request, *args, **kwargs):
uuid = kwargs.get('uuid')
resp = {'site': None}
site = Site.objects.get(uuid=uuid)
resp['site'] = SiteSerializer(site).data
return Response(resp)
urls.py
from django.conf.urls import re_path
from rest_framework.routers import DefaultRouter
from site_config import views
router = DefaultRouter()
router.register(
r'site',
views.SiteViewSet,
basename='site')
urlpatterns = [
re_path(r'^v1/', include(router.urls)),
re_path('test/<uuid:uuid>/', views.Test.as_view(), name='test'),
]
models.py
site id as the pk
class Site(models.Model):
"""
Model that represents a Site
"""
uuid = models.UUIDField(
default=uuid.uuid4,
editable=False,
unique=True)
domain_name = models.CharField(max_length=255, unique=True)
created = models.DateTimeField(editable=False, auto_now_add=True)
modified = models.DateTimeField(editable=False, auto_now=True)
serializers.py
class SiteSerializer(serializers.ModelSerializer):
class Meta:
model = Site
fields = [
'uuid',
'domain_name'
]
FYI - the endpoint was working when the views.py was returning all Sites, but it isn't working when I try to filter on uuid.
views.py (previously working version)
class Test(APIView):
def get(self, request, *args, **kwargs):
resp = {'site': None}
site = Site.objects.all()
resp['site'] = SiteSerializer(site, many=True).data
return Response(resp)
Error Message on Browser:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/v1/test/7c018183-c952-4040-a450-e3cb58f09745/
Using the URLconf defined in site_config.urls, Django tried these URL patterns, in this order:
^v1/ ^site/$ [name='site-list']
^v1/ ^site\.(?P<format>[a-z0-9]+)/?$ [name='site-list']
^v1/ ^site/(?P<uuid>[^/.]+)/$ [name='site-detail']
^v1/ ^site/(?P<uuid>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='site-detail']
^v1/ ^$ [name='api-root']
^v1/ ^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
test/<uuid:uuid> [name='test']
urls.py
As this is a routing problem the first place to have a look should be the urls.py.
Without recreating the app it looks like there are potentially three problems there:
Analysis
1. re_path
re_path is used, a regular Django path expression is provided. The django.urls documentation has some examples that speak for themselves.
2. the path itselt
The URL path starts with v1/ while the provided configuration starts with test/.
3. the order
As the re_path for ^v1/ matches anything beginning with v1/ the order in the pattern is important.
Anything that should available in that path must either be listed before the regex match, or be registered in the router.
Fix
urlpatterns = [
path('v1/test/<uuid:uuid>/', views.Test.as_view(), name='test'),
re_path(r'^v1/', include(router.urls)),
]
FYI - the endpoint was working when the views.py was returning all
Sites, but it isn't working when I try to filter on uuid.
As I do not have the breakpoint analysis for your views.py code I assume that your get method inside
class Test(APIView):
def get(self, request, *args, **kwargs):
uuid = kwargs.get('uuid')
resp = {'site': None}
site = Site.objects.get(uuid=uuid)
resp['site'] = SiteSerializer(site).data
return Response(resp)
is not getting resolved by the patterns in your urls.py or the uuid is not getting through.
If the case is former here what you can do is a direct mapping of the UUID inside the get method and avoiding the kwarg.get() by doing this
class Test(APIView):
def get(self, request, uuid, *args, **kwargs):
uuid = uuid
resp = {'site': None}
site = Site.objects.get(uuid=uuid)
resp['site'] = SiteSerializer(site).data
return Response(resp)

Reverse not found in Django

This might be a simple one but I have been on this for hours, I must be missing something. Here we go:
urls.py:
urlpatterns = [
# Event patterns
url('^$', views.BuddyProgram.as_view(), name='buddy_program'),
url('^dashboard/$', views.BuddyDashboard.as_view(), name='buddy_dashboard'),
url('^thank-you/$', views.BuddyFinal.as_view(), name='final'),
url('^completed_intro/$', views.CompletedIntro.as_view(), name='buddy_completed_intro'),
url('^completed_passive_track/$', views.CompletedPassiveTrack.as_view(), name='buddy_completed_passive_track'),
url('^about/$', views.BuddyAbout.as_view(), name='buddy_about'),
url('^list/$', views.Buddies.as_view(model=BuddyProfile), name='buddies'),
url('^signup/$', views.BuddySignupView.as_view(), name='buddy_signup'),
# url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
url(r'^(?P<buddy_id>[0-9]+)/$', views.Buddy.as_view(model=BuddyProfile), name='buddy'),
]
views.py:
class BuddyFinal(TemplateView):
template_name = 'buddy/thank_you.html'
class BuddySignupView(SignupView):
template_name = 'buddy/buddy_create.html'
success_url = reverse('final') # profile specific success url
form_class = BuddySignupForm
profile_class = BuddyProfile # profile class goes here
def form_valid(self, form):
response = super(BuddySignupView, self).form_valid(form)
profile = self.profile_class(user=self.user)
profile.save()
return response
and the error I get:
django.core.urlresolvers.NoReverseMatch: Reverse for 'final' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
As your URLs aren't loaded yet when importing the BuddySignupView (and thus executing reverse), Django cannot find the URL.
You should use reverse_lazy instead: https://docs.djangoproject.com/en/1.11/ref/urlresolvers/#reverse-lazy
In your views.py file:
from django.core.urlresolvers import reverse_lazy
class BuddySignupView(SignupView):
template_name = 'buddy/buddy_create.html'
success_url = reverse_lazy('final') # profile specific success url
reverse_lazy only reverse the URL name at "runtime" (when Django actually needs the value) instead of "import time" when everything may not be available yet.
This error is coming because in any template file you are accecsing url(thank-you or signup) in wrong format. make sure about this url in html.

Redirecting a View to another View in Django Python

How does one redirect from one View to another (next-going one):
class FooView(TemplateView):
template_name 'foo.html'
def post(self, *args, **kwargs):
return redirect(BarView)
# return redirect(BarView.as_view()) ???
class BarView(TemplateView):
template_name 'bar.html'
Give the URL pattern itself a name in your urls.py:
url('/bar/', BarView.as_view(), name='bar')
and just pass it to redirect:
return redirect('bar')
You can use the redirect for that, if you've given the view a name in urls.py.
from django.shortcuts import redirect
return redirect('some-view-name')
You need to give the view name "bar" to the path in "myapp/urls.py" as shown below:
# "myapp/urls.py"
from django.urls import path
from . import views
app_name = "myapp"
urlpatterns = [ # This is view name
path('bar/', views.BarView, name="bar")
]
Then, you need the conbination of the app name "myapp", colon ":" and the view name "bar" as shown below. In addition, you don't need to import the view "bar" in "myapp/views.py":
# "myapp/views.py"
from django.shortcuts import redirect
def FooView(request):
# Here
return redirect("myapp:bar")
def BarView(request):
return render(request, 'myapp/index.html', {})

Categories