Redirect to url from "post-only" view - django

I have the following setup for a combination of a DetailView and a FormView:
class EventBookView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
view = EventBookBaseView.as_view()
return view(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
view = EventBookFormView.as_view()
return view(request, *args, **kwargs)
class EventBookBaseView(DetailView):
template_name = "event_book.html"
model= Event
context_object_name = 'event'
class EventBookFormView(SingleObjectMixin, FormView):
template_name = "event_book.html"
form_class = PersonalInfoForm
model = Event
context_object_name = 'event'
def post(self , request , *args , **kwargs):
#do stuff
...
return redirect('user_bookings')
Unfortunately, the redirect to the url with the name 'user_bookings' is not working. How can I redirect to that url?
thanks!

You can use success_url, when Form is properly processed then view is redirected.
eg.
class MyFormView(FormView):
success_url = reverse_lazy('user_bookings')
EDIT: changed reverse to reverse_lazy

A POST method should not return a redirection.
If you need so, try to use HttpResponseRedirect.
Like:
return HttpResponseRedirect('/user_bookings/')

Related

#permission_required decorator returns no user attribute in View error

I'm working with Django-admin panel. I have created a custom view file to add a file manager.
To make file uploading safe, I just added permission_required decorator. But it throws an error 'FileBrowser' object has no attribute 'user'.
Here is my code.
class FileBrowser(ListView):
model = File
paginate_by = 30
template_name = "file_manager/browser.html"
extra_context = {
'file_type': type,
'title': "Media Browser",
}
#permission_required('file_manager.view_file')
def dispatch(self, request, *args, **kwargs):
file_type = request.GET.get('type')
self.queryset = File.objects.filter(type=file_type)
self.extra_context['value_to'] = request.GET.get('value_to')
self.extra_context['image_to'] = request.GET.get('image_to')
self.extra_context['form'] = FileForm()
return super().dispatch(request, *args, **kwargs)
You can not decorate the method like that, since such decorator does not expect self as first parameter. It thus sees self as the request parameter.
What you can do is work with a #method_decorator decorator, like:
from django.utils.decorators import method_decorator
#method_decorator(permission_required('file_manager.view_file'), name='dispatch')
class FileBrowser(ListView):
# …
def dispatch(self, request, *args, **kwargs):
# …
For a class-based view however, you can work with the PermissionRequiredMixin [Django-doc]
from django.contrib.auth.mixins import PermissionRequiredMixin
class FileBrowser(PermissionRequiredMixin, ListView):
permission_required = 'file_manager.view_file'
# …
def dispatch(self, request, *args, **kwargs):
# …
There was a small mistake in my code. But I didn't noticed that. I simply forgot to use #method_decorator and directly wrote #permission_required decorator.
This was what I wrote.
#permission_required('file_manager.view_file')
def dispatch(self, request, *args, **kwargs):
.......
.......
return super().dispatch(request, *args, **kwargs)
This is what I changed to:
#method_decorator(permission_required('file_manager.view_file'))
def dispatch(self, request, *args, **kwargs):
.......
.......
return super().dispatch(request, *args, **kwargs)
Now it's working fine.

How can i use middleware decorator for class-based view in djabgo?

How can i use middleware decorator for classbased view?
class APIViewMixin():
apiMiddleware = decorator_from_middleware(APISecretMiddleware)
#apiMiddleware
def dispatch(*args, **kwargs):
return super().dispatch(*args, **kwargs)
class ThemesView(APIViewMixin, View):
def get(self, request, id= None, *args, **kwargs):
if (id!= None):
serializer = vocabulary.customserializers.ThemesSerialiser(showWords=True);
return HttpResponse(serializer.serialize([vocabulary.models.Theme.objects.get(pk= id)]), content_type='application/json')
else:
serializers = vocabulary.customserializers.ThemesSerialiser(showWords=False);
return HttpResponse(serializers.serialize(vocabulary.models.Theme.objects.all()), content_type='application/json',)
this doesnt work

how to access session variable inside form class

Hi i have a session variable city, how to access it inside form class.
Something like this
class LonginForm(forms.Form):
current_city=request.city
A Form has by default no access to the request object, but you can make a constructor that takes it into account, and processes it. For example:
class LonginForm(forms.Form):
def __init__(self, *args, request=None, **kwargs):
super(LonginForm, self).__init__(*args, **kwargs)
self.request = request # perhaps you want to set the request in the Form
if request is not None:
current_city=request.city
In the related views, you then need to pass the request object, like:
def some_view(request):
my_form = LonginForm(request=request)
# ...
# return Http Response
Or in a class-based view:
from django.views.generic.edit import FormView
class LonginView(FormView):
template_name = 'template.html'
form_class = LonginForm
def get_form_kwargs(self, *args, **kwargs):
kwargs = super(LonginView, self).get_form_kwargs(*args, **kwargs)
kwargs['request'] = self.request
return kwargs

Django class based views: variable across classes

I have a mixin called GroupAwareMixin in a mixins.py file:
class GroupAwareMixin(object):
group = None
def get_group(self):
self.group = self.bridge.get_group()
def dispatch(self, request, *args, **kwargs):
if not self.group:
self.get_group()
In the views.py file I have the following ListView which inherits from the above GroupAwareMixin:
class ChatListView(LoginRequiredMixin, GroupAwareMixin, ListView):
model = Chat
template_name = 'chat/home.html'
Further I have a Chat class in my views.py file, where I would like to access the group variable from the GroupAwareMixin class above. How I am able to access the group variable in the Chat class?
class Chat(ws.WS, ChatListView):
def on_message(self, websocket, msg):
slug = self.group
I tried to inherit from ChatListView, but the self.group in the Chat class is None.
The LoginRequiredMixin defines the following:
class LoginRequiredMixin(AccessMixin):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
if self.raise_exception:
raise PermissionDenied # return a forbidden response
else:
return redirect_to_login(request.get_full_path(),
self.get_login_url(),
self.get_redirect_field_name())
return super(LoginRequiredMixin, self).dispatch(
request, *args, **kwargs)

Why does UpdateView need to have model/queryset/get_queryset defined when using form_class as opposed to CreateView?

Works like a charm:
MyCreateView(CreateView):
template_name = "my_template_name"
form_class = MyModelForm
success_url = "/success/"
But the following doesn't:
MyUpdateView(UpdateView):
template_name = "my_template_name"
form_class = MyModelForm
success_url = "/success/"
I get this error:
MyUpdateView is missing a queryset. Define MyUpdateView.model, MyUpdateView.queryset, or override MyUpdateView.get_queryset().
Why does an UpdateView need model, queryset or get_queryset defined to not cause an error while CreateView doesn't? Shouldn't it be able to automatically derive it from the Model used in the ModelForm?
Currently (django 1.5.1 official release) UpdateView is calling self.get_object() to be able to provide instance object to Form.
From https://github.com/django/django/blob/1.5c2/django/views/generic/edit.py#L217:
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(BaseUpdateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(BaseUpdateView, self).post(request, *args, **kwargs)
And self.get_object method needs one of this properties declared: model, queryset or get_queryset
Whereas CreateView don't call self.get_object().
From https://github.com/django/django/blob/1.5c2/django/views/generic/edit.py#L194:
def get(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).post(request, *args, **kwargs)
You might have a problem in your urls.py file.
What I think you wrote in it is:
url(r'foldername/(?P[0-9]+)/$', views.UpdateView.as_view(), name='update'),
but you have to change UpdateView to MyUpdateView, like this:
url(r'foldername/(?P[0-9]+)/$', views.MyUpdateView.as_view(), name='update'),