I have a bit of a problem with my view here as it is returning an error on django but I don't know what I have done wrong. My code is as follows in my view:
from django.views.generic import TemplateView
from django.shortcuts import render
from community.models import Community
class CommunityLanding(TemplateView):
def get_context_data(request):
template_name = 'community/landing.html'
objects = Community.objects.all()
context = {
'object': objects
}
return render(request, template_name, context)
Can anyone point me in the right direction?
Almost everything about your code is wrong. The template_name attribute is defined inside the class not inside the get_context_data method. The get_context_data method only takes one parameter and it is the 'self' variable, and should only return the context. You don't need to render your template manually, other methods take care of that as long as you have the template_name defined.
from django.views.generic import TemplateView
from community.models import Community
class CommunityLanding(TemplateView):
template_name = 'community/landing.html'
def get_context_data(self):
context = super().get_context_data()
objects = Community.objects.all()
context['object'] = objects
return context
You should read more about subclassing the generic views
Related
What I want to do is I'd like to call the module( RSAtest ) already created in view in Django. I am calling a function in RSAtest module from AboutPageView. But for some reason, it shows the following error: ModuleNotFoundError: No module named 'webapp.functional' Could you give me an idea how to use modules in Django?
# howdy/views.py
from django.shortcuts import render
from django.views.generic import TemplateView
from webapp.functional import RSAtest
class HomePageView(TemplateView):
def get(self, request, **kwargs):
return render(request, 'index.html', context=None)
# Add this view
class AboutPageView(TemplateView):
RSAtest.main()
#os.system('python3 howdy/RSAtest.py')
template_name = "about.html"
Thanks for the any help.
This is the views.py file:
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import Report
import random
class HomePageView(TemplateView):
def get(self, request, **kwargs):
args = {}
data = Report.objects.all()
args['data'] = data
return render(request, 'index.html',args)
I'm finding it difficult to understand the framework since I'm a beginner. So please help me.
You are trying to use class base view which will be different from function base view, to pass context data to template in class base view you need to override get_context_data method as below:
class HomePageView(TemplateView):
""" Home page view """
template_name = "index.html"
def get_context_data(self, **kwargs):
# first of all calling it's parent class method to get context (if any)
context = super(HomePageView, self).get_context_data(**kwargs)
# now you can update context dictionary as below:
context['data'] = Report.objects.all()
return context
Now you can access data in your template using {{ data }}
You can display the FileField content by passing the following
{{ context_obj.file_field_name.url }} in the template.
I've been learning Django and one source of confusion I have is with class based views and when to override the get method. I've looked through the documentation and it explains what get does but it doesn't explain when I should override get.
I originally created a view this way:
class ExampleView(generic.ListView):
template_name = 'ppm/ppm.html'
paginate_by = 5
def get(self, request):
profiles_set = EmployeeProfile.objects.all()
context = {
'profiles_set': profiles_set,
'title': 'Employee Profiles'
}
return render(request, self.template_name, context)
But I was recently told that my code was simple of enough for the default implementation, and that all I needed was this:
class ExampleView(generic.ListView):
model = EmployeeProfile
template_name = 'ppm/ppm.html'
So my Question is this: In what scenario/circumstance should I override the get method?
If you are using the builtin generic views, then you should rarely have to override get(). You'll end up either duplicating lots of functionality, or break features of the view.
For example, the paginate_by option will no longer work in your view, because you are not slicing the queryset in your get() method.
If you are using a generic class based view like ListView, you should try to override specific attributes or methods where possible, rather than overriding get().
The advantage of your view which overrides get() is that it's very clear what it does. You can see that the view fetches a queryset, includes it in a context, then renders the templates. You don't need to know about ListView to understand the view.
If you like the explicitness of overriding get() subclass View instead. You aren't using any of the features of ListView, so it doesn't make sense to subclass it.
from django.views.generic import View
class ExampleView(View):
template_name = 'ppm/ppm.html'
def get(self, request):
...
You should override the get method when you specifically want to do something other than the default view does. In this case, your code isn't doing anything other than rendering the template with the list of all EmployeeProfile objects, which is exactly what the generic ListView would do.
You might override it if you want to do something more complicated. For example, maybe you want to filter based on a URL parameter:
class ExampleView(generic.ListView):
template_name = 'ppm/ppm.html'
def get(self, request):
manager = request.GET.get('manager', None)
if manager:
profiles_set = EmployeeProfile.objects.filter(manager=manager)
else:
profiles_set = EmployeeProfile.objects.all()
context = {
'profiles_set': profiles_set,
'title': 'Employee Profiles'
}
return render(request, self.template_name, context)
I am trying to pass a queryset object to django context class, but doing so results in the following error: TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
Now i understand that the context accepts only a dictionary but i am following an example from a book called django_unleashed which uses Django version 1.8 and i am using django 2.0. and i guess it was done like that in previous versions.
So my question is how should i do this step correctly using django 2.0
from django.shortcuts import render
from django.http import HttpResponse
from .models import Tag
from django.template import Context, loader
def homepage(request):
tag_list = Tag.objects.all()
template = loader.get_template('organizer/tag_list.html')
context = Context({'tag_list': tag_list})
output = template.render(context)
return HttpResponse(output)
As the error suggests, you should use a regular dictionary for the context:
def homepage(request):
tag_list = Tag.objects.all()
template = loader.get_template('organizer/tag_list.html')
context = {'tag_list': tag_list}
output = template.render(context)
return HttpResponse(output)
In practice, you would usually use the render shortcut rather than manually rendering the template:
from django.shortcuts import render
def homepage(request):
tag_list = Tag.objects.all()
context = {'tag_list': tag_list}
return render(request, 'organizer/tag_list.html', context)
'''you have a model class named 'Tag',
wish your template is on ' Project directory/ app directory/ template/ same name of app directory'
example: let your project name is 'Website' and app name is 'organizer' then the template will be on: 'Website/ organizer/ templates/ organizer/ tag_list.html' Confirm your TEMPLATES setting is default on setting.py file."'
from django.shortcuts import render
from .models import Tag
def homepage(request):
tag_list = Tag.objects.all()
context = { 'tag_list' : tag_list}
return render ( request, 'organizer/tag_list.html', context)
Edited: I am trying to update the value of a single field inside one of Django's objects. Here is the code:
class TodoCompleteView(generic.DetailView):
queryset = Todo.objects.all()
def get_object(self):
# Call the superclass
object = super(TodoCompleteView, self).get_object()
# Record the last accessed date
object.todo_completed = True
object.save()
# Return the object
return object
However, I keep getting an error:
TemplateDoesNotExist at /8/complete
list/todo_detail.html
How can avoid this? I simply want this view to flip a certain value in DB.
You inherit view from DetailView class, which by default is to view some models and not to change. Also, apparently, you use GET request to change the data. This is the wrong approach.
Alternatively I advise you to try to make inherit your view from SingleObjectMixin and View and manually create a handler for POST request.
I would rewrite your example like this:
from django.views.generic import View
from django.views.generic.detail import SingleObjectMixin
class TodoCompleteView(SingleObjectMixin, View):
model = Todo
def post(self, *args, **kwargs):
self.object = self.get_object()
self.object.todo_completed = True
self.object.save(update_fields=('todo_completed', ))
return HttpResponse(status=204)
P.S. you get the error, because DetailView subclassed from SingleObjectTemplateResponseMixin which tries to render the template called <model_name>_detail.html.