How to delete a django object inline with jquery - django

To delete an object I inherit from DeleteView which has 3 steps (user clicks on delete, goes to confirm page, click yes again, redirected to success page) How can I make it more inline (user clicks delete, alert window pops up asking user to confirm, user confirms, the object is gone, user is still on the same page)
url(r'^(?P<username>\w+)/recipientbank/delete/(?P<pk>\d+)/$', RecipientBankAccountDeleteView.as_view(model=RecipientBankAccount)),
url(r'^(?P<username>\w+)/recipientbank/delete/(\d+)/success/$',recipientbank_deleted,name='recipientbank_deleted'),
class RecipientBankAccountDeleteView(DeleteView):
form_class = RecipientBankAccountForm
success_url='success'
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
self.object.delete()
return HttpResponseRedirect(self.get_success_url())
def recipientbank_deleted(request, username, public_profile_field=None,template_name='main/recipientbankaccount_deleted.html',extra_context=None):
return render(request, template_name)

You should use django-piston to create RESTful APIs and make an AJAX call from your page to delete your django objects.
You can read about RESTful here: http://en.wikipedia.org/wiki/Representational_State_Transfer
and django-piston here: https://bitbucket.org/jespern/django-piston/wiki/Home
I've heard that you could achieve this with Generic Views starting django version 1.3, but I haven't used it.

Related

Handling user registrations Using only Django without the need to be redirected to other template

This is my view
class UserRegistrationView(FormView):
template_name = "register/register_form.html"
form_class = None
extra_fields_form_page_slug = ""
email_template = "register/account_activation_email.html"
def get_form(self, form_class=None):
form = super().get_form(form_class)
add_extra_fields(
form.fields, form.helper.layout.fields, self.extra_fields_form_page_slug
)
return form
def get_extra_form(self):
return FormPage.objects.filter(slug=self.extra_fields_form_page_slug).first()
def form_valid(self, form):
user = form.save(commit=False)
user.is_active = False
user.save()
email = form.cleaned_data.get("email")
email_template = "register/account_activation_email.html"
send_confirmation_email(
self, "Activate Your Account", user, email, email_template
)
return render(self.request, "register/after_submission.html")
This is working fine (registration wise) but it's not from many other sides, because I have the registration form as a pop up window in the header, so it's available throughout the whole website, my problems are:
if the user had a successful registration they will be redirected to the specified template "after_submission" what I want is to stay on the same page and display a pop up with some message
if the user had an unsuccessful registration they will be redirected to the main template "register_form.html" with the errors displayed their, what I want is to stay on the same page and to display the error messages on the pop up form if the user opened it again
is this achievable using only Django?? or I must throw some JS in there, and if JS is the answer, can you give me a quick insight into how to do it?
You can redirect to the same page in your CBV :
from django.http import HttpResponseRedirect
return HttpResponseRedirect(self.request.path_info)
As stated in the comment your solution require Ajax and JS, you can however redirect to the same page but that will make a new request and refresh the whole page which might no be ideal for you.
There is a tutorial to work with Django and Ajax Ajax / Django Tutorial

Django use data in a class based view

I have a class-based view in Django.
I have implemented a method get_context_data. A user can log in or update his/her data and is redirected to a class-based view template.
I want the information of the logged-in user inside the class-based view. I'm not rendering the view, just re-directing. Is there any approach like saving the data in memory during computation or global variables so that it can be accessed anywhere in the views.py.
if the user is logging in using the authenticate/login method, and you have the SessionMiddleware loaded as you should, then the user information should be in your request.user object.
In a class-based View object you can read the request like so:
class SomeView(View):
def get(self, *args, **kwargs):
user = self.request.user
#recommended: check if the user is authenticated, ie, not anonymous.
if user.is_authenticated:
check_something(user) #do whatever you need.
in the case of TemplateView subclasses (I assume, since you mention get_context_data) is the same:
class SomeTemplateView(TemplateView):
def get_context_data(self, *args, **kwargs):
if self.request.user and self.request.user.is_authenticated:
#do something
Globals and other things won't work in a Django service, it might work on development, but in production, your user's request could be handler by different python processes altogether and memory won't be shared between them.

Django fresh login required on accessing profile page

I am new to django and writing authentication system for my application. Right now I have built the basic login/logout functionality.
What I want is that whenever a logged in user wants to access their profile page, they should be asked to confirm their password.
I have searched this on django docs but I was not able to find any resource on how to achieve. I know flask has a fresh_login_required decorator which does this, just wondering if it is possible to do the same thing with django as well.
I don't think there is any function for this in django. But you can write on your own with help of django session. For example:
First, we need to write a decorator:
# decorator
def require_fresh_login(function):
#wraps(function)
def wrap(request, *args, **kwargs):
has_verified_profile = request.session.pop('has_login_verified',None)
if has_verified_profile:
return function(request, *args, **kwargs)
else:
return redirect(reverse('fresh_password_view_url'))
return wrap
Then there should be a view for fresh_password_view_url, where you need to put a value against key has_login_verified in request.session. For example:
def verify_fresh_password(request):
form = SomeForm(request.POST)
if form.is_valid():
password = form.cleaned_data.get('password')
if request.user.check_password(password):
request.session['has_login_verified'] = True
return redirect('profile_view')
# else send error response

Using get_success_url on a DeleteView when relevant data has been removed

In a Django application working with recipes I have subclassed DeleteView to create my IngredientListItemDeleteView, but I would like the result of get_success_url to depend on a property of the item that was just deleted.
I would like to do something like this:
def get_success_url(self):
item = get_object_or_404(IngredientListItem, pk=self.kwargs['pk']) # -> 404
return this_item.recipe.get_absolute_url()
I understand that I get a 404 error because the item in question no longer exists but I have had no luck storing the relevant information about the item (namely, its containing recipe) before it gets deleted. For instance, if I put into the get method any code like
self.success_url = get_object_or_404(IngredientListItem,
pk=self.kwargs['pk']).recipe.get_absolute_url()
then by the time success_url is looked at (after deletion), it has the value None.
How can I make my success URL depend on this property of the deleted item?
In Django 1.6, the delete method has been changed so that the get_success_url method is called before the object is deleted.
def delete(self, request, *args, **kwargs):
"""
Calls the delete() method on the fetched object and then
redirects to the success URL.
"""
self.object = self.get_object()
success_url = self.get_success_url()
self.object.delete()
return HttpResponseRedirect(success_url)
I recommend you override your delete method as above, until you upgrade to Django 1.6. If you need to do this for multiple classes, you could create a mixin.
Note that you don't need to fetch the item from the database with get_item_or_404 -- you can access it in your get_success_url method as self.object.

Django class-based view - DeleteView - How to disable confirmation requirement

I am switching to the class-based views. I also use JavaScript to confirm any deletion on the client side. Django DeleteView requires a delete confirmation template which I don't care about.
Is there any simple way of disabling the confirmation on any kind of deletes in Django?
class EntryDeleteView(DeleteView):
model = Entry
success_url = reverse_lazy('entry_list') # go back to the list on successful del
template_name = 'profiles/entry_list.html' # go back to the list on successful del
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(EntryDeleteView, self).dispatch(*args, **kwargs)
You should make a POST query from clientside (with AJAX or POSTing a form). That's because if you'll allow to delete something by GET, your service will be vulnerable to CSRF. Someone will send your admin a in email or somehow else, and you'll be in trouble.
The DeleteView renders the confirmation page on GET and deletes the object if you use a POST or DELETE. If your JS does a POST to the url after confirmation it should work like you want.