Django: Passing string parameters to class-based view not working - python

I have tried following this suggestion to pass string parameters to a class based view but it does not seem to work.
the url:
url(r'^chart/(?P<chart_name>\w+)/$',
ChartView.as_view(chart_name='chart_name'), name="chart_url"),
the view:
class ChartView(View):
template_name = "chart.html"
chart_name = None
def post(self, request, *args, **kwargs):
form = DatesForm(request.POST)
context = {
'form': form
}
return render(request, self.template_name, context)
def get(self, request, *args, **kwargs):
print("test")
form = DatesForm()
# fetch plot data (default values used)
context = {
'form': form,
'chart_name': self.chart_name
}
return render(request, self.template_name, context)
the link that is supposed to be redirecting to the view:
Sometext
(namespace 'chartboard' given in the project's urlconf).
the error:
NoReverseMatch at /chart/lords/
Reverse for 'chart_url' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['chart/(?P<chart_name>\\w+)/$']
For what its worth, "test" gets printed twice to the console output (why?)
Using django 1.8.11 and python 3.4.3 on Ubuntu 14.04.04

You should access the chart_name using kwargs:
# urls.py
url(r'^chart/(?P<chart_name>\w+)/$',
ChartView.as_view(), name="chart_url"),
# and then in the view
class ChartView(View):
template_name = "chart.html"
def get(self, request, *args, **kwargs):
form = DatesForm()
context = {
'form': form,
'chart_name': kwargs['chart_name'] # here you access the chart_name
}
return render(request, self.template_name, context)
The post you have considered for implementing this is for making sure that a variable is available in templates and that is taken care of by setting it up in context which is passed to the template render.
The problem you are facing here is to access a named group defined in the url pattern.
Here is more documentation on how django process a request when you try to access a URL.

Related

any direct method to Access dynamic url in post method

in views.py
class ProcessMessage(TemplateView):
template_name = 'chat/chat.html'
def get_object(self):
id=self.kwargs.get('pk')
obj=None
if id is not None:
obj= User.objects.get(pk=id)
return obj
def get(self, request, pk=None,*args, **kwargs):
obj=self.get_object()
print(obj,pk)
super(ProcessMessage, self).get(request, *args, **kwargs)
return render(request, self.template_name, {'form': ChatForm()})
def post(self, request, pk=None,*args, **kwargs):
obj=self.get_object()
pk=pk
print(pk)
print('obj is',obj)
form = ChatForm(data=request.POST)
# log = logging.basicConfig(level=logging.DEBUG)
# print('post from index')
if form.is_valid():
//////something////
in urls.py
app_name = 'chatbot'
urlpatterns = [
path('demo', views.ProcessMessage.as_view(), name='index'),
path('<uuid:pk>/demo', views.ProcessMessage.as_view(), name='index'),
]
I am getting the value of obj and pk inside get method but I want those value inside post method also(getting value None currently)
I need id/pk from URL in def Post method to get user information(no I don't want to use request.user)
Your template shows that you are submitting the form to a URL without a pk:
{% url 'chat:index' %}
You should include the pk when reversing the URL, e.g.
{% url 'chat:index' pk %}
You'll need to include the pk in the template context, e.g.
return render(request, self.template_name, {'form': ChatForm(), 'pk': pk})
I see that you are using the same view ProcessMessage for /demo/ and /<pk>/demo/. I would recommend using a different view for both URLs, I think it would help avoid issues like this.

Get context from another CBV with Django

I would like to get your help in order to use context from a Django CBV in another CBV through get_context_data().
Objective:
Basically, I have a django ListView() with pagination. I pick up the current page in get_context_data(). Then, I would like to edit an object, so I'm going to UpdateView().
When I post the edit, it should return to the previous pagination. For example, if the object was on page 32, after the POST request, I need to be redirected to page 32.
My code:
class DocumentListView(AdminMixin, CustomListSearchView):
""" Render the list of document """
def get_context_data(self, **kwargs):
context = super(DocumentListView, self).get_context_data(**kwargs)
actual_page = self.request.GET.get('page', 1)
if actual_page:
context['actual_page'] = actual_page
return context
class DocumentFormView(CustomPermissionRequiredMixin, DocumentListView, UpdateView):
def get_current_page(self, **kwargs):
context = super(DocumentListView, self).get_context_data(**kwargs)
actual_page = context['actual_page']
return actual_page
def get_context_data(self, **kwargs):
context = super(DocumentFormView, self).get_context_data(**kwargs)
print(self.get_current_page())
...
return context
def post(self, request, pk=None):
...
return render(request, 'app/manage_document_form.html', context)
Issue:
I don't overcome to get the actual_page in my class DocumentFormView.
I got this issue :
AttributeError: 'DocumentFormView' object has no attribute 'object'
I tried to add in my post() function :
self.object = self.get_object()
But it doesn't solve the issue.
Do you have any idea ?

Kwargs isnt passing

I am trying to pass some information to a view in Django in order to filter a list and then pass this back to the user. In order to do so I have the following in my urls.py:
url(r'^info/user/(?P<user_id>\d+)$', views.UserInfoView, name='active_reservations'),
and the following view defined:
def UserInfoView(request, **kwargs):
template = "parking/detail_user.html"
user = User.objects.filter(user=self.kwargs['user_id'])
context = {"user": user}
return render(request, template, context)
However, each time I try this I get the error: NameError at /info/user/1
global name 'self' is not defined
Any ideas?
You should change the view function. Replace **kwargs with user_id
def UserInfoView(request, user_id):
template = "parking/detail_user.html"
user = User.objects.filter(user=user_id)
context = {"user": user}
return render(request, template, context)
kwargs is not an attribute of self. Your code should be:
user = User.objects.filter(user=kwargs['user_id'])

Struggling to understand a django class based view code

I was reading the docs for the django class based view when I encountered a code that I couldn't really understand. If someone could explain the "get" part it would be really helpful.
here is the view code
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.views.generic import View
from .forms import MyForm
class MyFormView(View):
form_class = MyForm
initial = {'key': 'value'}
template_name = 'form_template.html'
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
# <process form cleaned data>
return HttpResponseRedirect('/success/')
return render(request, self.template_name, {'form': form})
What's the "initial" for ? And how the get function is contributing to this code?
The get function renders the form, i.e. produces HTML of the form. When given a dictionary of initial values, then even on the first visit, the form will already be filled — with the initial values. Otherwise it would be empty.
The class variable initial is merely storing the initial values, so they can be used by the get function. You could put the variable also in the get method or omit it entirely:
def get(self, request, *args, **kwargs):
form = self.form_class(initial={'key': 'value'})
return render(request, self.template_name, {'form': form})
(Would not do it though, as the initial values are then slightly less visible, and they really are important.)
Also, have a look at the documentation regarding bound and unbound forms, to understand the difference between initial and default values.
initial = {'key': 'value'}
is a place to set some default values for the form.
self.form_class(initial=self.initial)
uses those defaults to fill the form when there is a GET request.

Django: How to provide context into a FormView get() method (also using request param)

I'm trying to provide some additional context into the get() method in my FormView. I need get() because I need to run some logic first, check for a potential redirect. I also need access to the request object (because I need to check session data). Can't figure out how to do it. Simplified code below..
Attempt 1:
class LoginView(FormView):
template_name = 'members/login.html'
form_class = LoginForm
def get(self, request):
# check if to redirect
if self.request.session.get('user'):
return redirect('/dashboard/')
# render page with extra context
else:
context = super(LoginView, self).get(request)
context['message'] = self.request.session['message']
return context
No errors, but context does not come through in the template.
Attempt 2:
class LoginView(FormView):
template_name = 'members/login.html'
form_class = LoginForm
def get_context_data(self, request, **kwargs):
# check if to redirect
if self.request.session.get('user'):
return redirect('/dashboard/')
# render page with extra context
else:
context = super(LoginView, self).get_context_data(**kwargs)
context['message'] = self.request.session['message']
return context
Getting TypeError: get_context_data() takes exactly 2 arguments (1 given)
P.S. This work relates to a workaround Django's buggy messages middleware which seems to be working locally flawlessly but on live (Heroku) is not 100% reliable, renders on some pages only. Ugh, frustration setting in...
Ditch the request argument to the get_context_data method. You should also use the dispatch method to check if the user is logged in.
class LoginView(FormView):
template_name = 'members/login.html'
form_class = LoginForm
def dispatch(self, *args, **kwargs):
"""Use this to check for 'user'."""
if request.session.get('user'):
return redirect('/dashboard/')
return super(LoginView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
"""Use this to add extra context."""
context = super(LoginView, self).get_context_data(**kwargs)
context['message'] = self.request.session['message']
return context

Categories

Resources