I am new to django and in my current job i had to edit the existing code.
Now i am not able to find in the documentation where i can find all methods which can be over ridden and what they are suppose to do.
In mY views file someone has defined these functions but i don't know what they are supposed to do.
Like
def get_context_data(self, **kwargs):
def get(self, request, *args, **kwargs):
def post(self, request, *args, **kwargs):
def get_success_url(self):
def form_valid(self, form):
Now i am not sure if he as write his new methods or He is overriding the buil in methods because he is not calling them anywhere.
can someone guide where are these methods defined in documentation so that i can see what are some other methods and what they do
I found this resource really uesful, as it saves you having to manually trace inheritance hierarchies to check which methods a class has.
http://ccbv.co.uk/
The official documentation is here, depending on your django version:
https://docs.djangoproject.com/en/1.3/ref/class-based-views/
https://docs.djangoproject.com/en/1.4/ref/class-based-views/
https://docs.djangoproject.com/en/dev/ref/class-based-views/
get_context_data returns the data that will be accessible in your template
get is all the actions that are performed when a page is loaded
post is all the actions that are performed when data is posted to a url
get_success_url returns the url that the user will be directed to after a post was succesfully made
form_valid here you can add extra actions to the form validation
Related
At the moment, I plan to write a website where users can write blog posts. I haven't started with the implementation yet because I am new to Django and want to get an overview in how I should solve problems and structure the overall project.
My problem:
The users aren't allowed to use Django's admin page (/admin). The users should only interact with the website that I write.
The users at my website will be able to create blog posts. Now, I have to ensure that only the creator of the blog post should be able to edit/delete his own post. All the other users should only be able to read this post.
So, I need permissions per user/instance. I know that there are some full-blown permission-systems like django-guardian, but I would like to prefer to solve it on my own. Also to better understand the Django framework.
I`ve already read the Django docs, but I am overwhelmed.
I guess this is such a common problem that I there is also a common solution to this problem. Can someone help me where I should look at, where to start?
My idea so far (please comment):
In create a page like blog/5/edit that is only accessible for the user that created the blog post number 5. This should be easily within the view function, right? On this page there is a Form to edit the blog post.
Something like this for the view (pseudo-code!)
if request.user != blogpost.user:
redirect/error page
else:
show Form/process Form
Is this secure? I haven't found such a solution so far while searching the internet. However, spontaneously and as a Django beginner, I think this could already by enough.
Yes, you can do that. For that purpose I recommend to create an custom decorator like so:
decorators.py:
from django.core.exceptions import PermissionDenied
from .models import YourBlogPostModel
def user_is_blog_post_user(function):
def wrap(request, *args, **kwargs):
post = YourBlogPostModel.objects.get(pk=kwargs['blog_post_id'])
if post.user == request.user:
return function(request, *args, **kwargs)
else:
raise PermissionDenied
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
You can then use it in conjunction with other decorators.
views.py:
#login_required
#user_is_blog_post_user
def function_based_view(request, blog_post_id):
# ...
Take a look here for a more detailed explanation.
If you are using CVB you can either create an own Mixin or decorate the class.
class UserIsBlogPostAdmin(object):
"""Verify that the current user is the user of the blog post."""
def dispatch(self, request, *args, **kwargs):
blog_post = get_object_or_404(YourBlogPostModel, pk=args[0])
if blog_post.user != request.user
raise Http404
return super().dispatch(request, *args, **kwargs)
I'am building an API using python 2.7 and django 1.7 and I'm facing a problem. I'm not an expert in Rest Framework but I understand the basic mechanisms.
I can resume my problem by giving you an example. I have a route lets say
/api/project/
Django Rest Framework provides me all basic operations for this route and I don't need to write them e.g:
POST, GET, PUT, DELETE => /api/project/
The fact is, I want to do some operation when I create a new project. I want to add the id of the user who has created the new project.
I want to add some kind of trigger/callback to the create function:
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
def create(self, request, *args, **kwargs):
I want to keep the internal behavior of Rest Framework (I don't want to rewrite the route functions), but I want the route to do extra stuff and I need the request object in my trigger/callback. Something like
def callback(request, instance):
instance.created_by = request.user
instance.save()
Do you have any ideas?
Thank you.
You need to add creator_id field to your serializer as well as to model represented by the resource. Then you can do something like this in your view:-
import copy
class ProjectViewSet(viewsets.ModelViewSet):
...
def create(self, request, *args, **kwargs):
data = copy.deepcopy(request.data)
data['creator_id'] = request.user.id
request._data = data
return super(ProjectViewSet, self).create(request, *args, **kwargs)
I have a created a view class "class Demo", which has 3 functions
def update_time()
def get_context()
def before_response()
urls.py : url(r'^demo/$', Demo.as_view(),name='demo_class'),
When i'll enter url /demo/ how will it determine which function to call from "class Demo" ?
Because Django’s URL resolver expects to send the request and associated arguments to a callable function, not a class, class-based views have an as_view() class method which serves as the callable entry point to your class. The as_view entry point creates an instance of your class and calls its dispatch() method. dispatch looks at the request to determine whether it is a GET, POST, etc, and relays the request to a matching method if one is defined, or raises HttpResponseNotAllowed if not.
just read the docs
Basically class based views are recommended when you need to handle both get and post requests at one point. For example in get method of class Register, you can render the registration form and in its post method, you can handle the form submission. If its a get request it will automatically invoke the get() method in the class, same for post request. Also you can write any common code in the dispatch() method which will be invoked for every request.eg:
class Register(View):
def dispatch(self, *args, **kwargs):
'''
common code here
'''
return super(Register, self).dispatch(*args, **kwargs)
def get(self, request):
registration_form = RegistrationForm()
return render(request, 'new.html', { 'form': registration_form })
def post(self, request):
registration_form = RegistrationForm(request.POST or None)
if registration_form.is_valid():
#save form
return HttpResponseRedirect(reverse('success-show'))
return render(request,new.html', { 'form': registration_form })
For references you can check this website.
You need to subclass a class based views, and depending on that it will have one or another method.
For example TemplateView renders a template you pass in the template_name attribute.
All class based views care about is that the attributes needed to work properly are setted. That is done via different methods. You can check the django's documentation for specifics.
For example, if you want to render a form in your template view, you will need to pass the form in the context, so you can override get_context_data() like:
def get_context_data(self, **kwargs):
context = super(DemoClass, self).get_context_data(**kwargs)
context['form'] = MyForm()
return context
There are different methods to handle different things, like querysets, objects, etc.
They are not complicated, but they are specific. If a class based view does not fit what you need, it may be easier to implement the functionality from a more general view (View, TemplateView) than forcing a more specific one to do things it is not intended for.
slightly change the url
add numbers one to three in url and put the condition in your view.
Ex.
url(r'^abc/(?P<newid>.*)$', 'class_demo'),
so your url will be like abc/1 or abc/2 or abc/3
view
def class_demo(requests, newid):
if newid==1:
update_time()
elif newid==2:
get_context()
For every user in my django application, I generate a static .ical file which I would like to serve. Is there a CBV for that and which method would I overwrite?
As all of my views are class based I' d rather not use a function-based view with a HttpResponse and a #auth_required decorator according to this:
Django: Serving a Download in a Generic View
Just inherit from the View model and override the view method.
class ICalDownload(View):
def get(self, *args, **kwargs):
# return your response just like you would in a function view.
If you want to protect the view, I like to use django-braces. Otherwise, you need to use method_decorator on the dispatch method:
#method_decorator(auth_required)
def dispatch(self, *args, **kwargs):
return super(ICalDownload, self).dispatch(*args, **kwargs)
At this point, a function based view might be a little simpler, but like you, I like to always use class based views.
I'm using Django 1.4. I've spent quite a while googleing and looking at docs on the django page, https://docs.djangoproject.com/en/1.4/ref/contrib/formtools/form-wizard/ etc. Few people have asked the question and no-one happens to have answered it.
What I need to do is:
use the slug paramater from the urls.py (as follows):
FORMS=[...]
url(r'^url/(?P<slug>[\w-]+)/form/$', WizardWizard.as_view(FORMS)),
in the views.py (as follows):
class WizardWizard(SessionWizardView):
template_name = "template.html"
extra_context = Model.objects.filter(slug=slug) # HERE!
def done(self, form_list, **kwargs):
...
Solved this problem too. FormWizard instance contains self.args and self.kwargs which are set to args and kwargs passed to view from URLconf. You can see it in django.views.generic.base.dispatch
After being stuck for days the answer is fairly simple. If you're reading this, make sure you're using Class based generic views first or it's a different problem.
You can find the relevant information on the following link, it's not clear this is how you assign extra context (not with the extra_context var):
https://docs.djangoproject.com/en/1.4/ref/contrib/formtools/form-wizard/#django.contrib.formtools.wizard.views.WizardView.get_context_data
example code (slightly different from theirs) that sets a context var for ALL of you formwizard pages:
def get_context_data(self, form, **kwargs):
context = super(PaperworkWizard, self).get_context_data(form=form, **kwargs)
#this line makes camp available as a var in the template context.
#it sets it to an OBJECT RETRIEVED USING THE SLUG FROM THE URL.
context.update({'camp': Camp.objects.get(slug=self.kwargs.get("slug"))})
return context
You need to put this code in the subclass you've made of the SessionWizardView (or CookieWizardView). In the context of the question, the WizardWizard class in the views.py file.
The problem with doing this any other way, is that the self.args and self.kwargs are set when the dispatch function is run. NOTE: You can't set the context by setting the extra_context variable This is where I fell down.
credit to nkryptic from the #django channel on freenode. It's a fantastic place to head if you are still stuck after this answer. I wish everyone the best of luck.