I'm working on a site that has some mostly static content that I still want to use Django template tags in. I don't want to have to write a view and add a urlconf entry for each URL, I just want to add templates to a specific folder and have them be rendered and accessible on the web. Is there already a project out there that does this?
Write a catch all view and resolve template dynamically:
from django.shortcuts import render_to_response
import django.template
import django.http
def view_template(request, template_name):
try:
return render_to_response(template_name)
except django.template.TemplateDoesNotExist:
raise django.http.Http404('No such file: %s' % template_name)
And in your url-conf add, towards the end:
url(r'^/(?P<template_name>[\w-]+\.html)$', view_template),
Related
How can i add a django template variable to href attribute of tag?something like this
{{meeting.meeting_url}}
meeting.url stores a link to another website such as google etc and it is saved in database
Thanks in advance
To render meeting.meeting_url in your template you need to pass the meeting object as argument of the render function in your view.
More about the render function here
Here's an example of what should be done:
from django.shortcuts import render
from .models import Meeting
def my_view(request):
# View code here...
context = {'meeting': Meeting.objects.first()} # first is an example, put whatever you want
return render(request, 'myapp/index.html', context)
You must make sure that your url (www.google.com) does start by a / because it would refer to the root url of your website (127.0.0.1:8000) which redirects you to 127.0.0.1:8000/meeting/meeting-info/www.google.com
I checked all the questions and answers in this site, but could not find a solution. I am new in Django, trying to develop a storage model and stucked already in the ListView.
part of my view.py:
from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from Storage.models import Storage
from django.http import HttpResponse
class StorageListView(LoginRequiredMixin, ListView):
model = Storage
print(Storage.objects.order_by('-barcode'))
template_name = 'Storage/Storagelist.html'
def get_queryset(self):
return Storage.objects.order_by('-barcode')
I add print statement to check whether I reach the model and
everyting seems normal:
<QuerySet [<Storage: 123>, <Storage: 122>, <Storage: 121>]>
However, I can not reach the context from the template file 'Storagelist.html':
<h3>trial</h3>
{% if storage_list %} <h3>trial</h3> {% endif %}
Just to check access via url configurations, I added 'trial' at the beginning of the template and it also seems normal. I also tried to use context_object_name, but did not help either. Somehow, I can not reach to ListView context data from the template.
My versions of applications are as follows:
Django 2.0.3
Python 3.6.1
Can somebody please help me?
In a ListView I believe the objects will populate into the template as object_list. You might consider using this method to make the template context variable human readable (and also match what you are expecting). In other words, try adding context_object_name = storage_list to your view.
In wagtail/django how do you make a basic wagtail Page model, create the html template, and then tell that model to serve as a view for a specific url?
from django.db import models
from wagtail.wagtailcore.models import Page
class MyPage(Page):
title = models.CharField(blank=True, null=True, max_length=255)
#...
I want the url to register like
url(r'^monkey/(?P<slug>[A-Za-z0-9]+)$', ...)
But I don't have a common urls.py folder its stored outside of the project. I tried using the RoutablePageMixin, but I believe that serves for subpages. I also know where to store the html template within the structure so that is not a problem.
You might want something like:
from django.http import Http404
from django.views import View
from wagtail.core.views import serve
class WagtailPageServeView(View):
"""
A default way to serve up wagtail pages in urls
"""
wagtail_slug = None
def get(self, request, *args, **kwargs):
if self.wagtail_slug:
return serve(request, self.wagtail_slug)
else:
raise Http404(
f"WagtailPageServeView missing 'wagtail_slug'. Cannot serve "
f"request.path: {request.path}"
)
Then you can do something like this in urls.py:
urlpatterns += [
re_path(r'^$', WagtailPageServeView.as_view(wagtail_slug='/'), name='home'),
]
In Wagtail, you are creating a page type and then creating instances of the page type in the CMS.
Even if you are only going to use this page once, you still need to make a type. Following this logic, page urls are defined inside the CMS through the page's parent and slug. Most likely, you could achieve what you want through these means.
If you want to override your page template and create a custom url, you can override the get_url_parts method on your model.
Also, if you want to skip Wagtail for this page specifically, remember that Wagtail is just built over Django. You can always create a new module and define the url in that model. If you check your site urls.py, you will see the wagtail url patterns. You can change it to look something like this:
urlpatterns = [
# other urls...
url(r'wagtail/', include(wagtail_urls)),
url(r'^monkey/', ('monkey_app.urls', 'monkey_app')),
]
I am updating a Django project which used the direct_to_template as a function ie:
return direct_to_template(request, 'bprofile/init.html', targs)
As described a short way down this page
I have seen the SO question here and read the documentation on this page which decribe the migration of statements of the form
('^about/$', direct_to_template, {'template': 'about.html'})
to look like
('^about/$', TemplateView.as_view(template_name='about.html'))
Unfortunatelty I cannot seem to figure out how to change statements from the form that I have into a working new form.
How might one modify this code to work with the new Templateview form?
You shouldn't be using the generic views for this, that's not what they are for. If you want to render a template, you should use the render shortcut: it takes exactly the same arguments.
return render(request, 'bprofile/init.html', targs)
To use TemplateView you import TemplateView into your urls.py:
from django.views.generic.base import TemplateView
Then you just add the urlconf:
('^about/$', TemplateView.as_view(template_name='bprofile/init.html'))
I am working on Django Project where I need to extract the list of user to excel from the Django Admin's Users Screen. I added actions variable to my Sample Class for getting the CheckBox before each user's id.
class SampleClass(admin.ModelAdmin):
actions =[make_published]
Action make_published is already defined. Now I want to append another button next to Add user button as shown in fig. . But I dont know how can I achieve this this with out using new template. I want to use that button for printing selected user data to excel. Thanks, please guide me.
Create a template in you template folder: admin/YOUR_APP/YOUR_MODEL/change_list.html
Put this into that template
{% extends "admin/change_list.html" %}
{% block object-tools-items %}
{{ block.super }}
<li>
Export
</li>
{% endblock %}
Create a view function in YOUR_APP/admin.py and secure it with annotation
from django.contrib.admin.views.decorators import staff_member_required
#staff_member_required
def export(self, request):
... do your stuff ...
return HttpResponseRedirect(request.META["HTTP_REFERER"])
Add new url into YOUR_APP/admin.py to url config for admin model
from django.conf.urls import patterns, include, url
class YOUR_MODELAdmin(admin.ModelAdmin):
... list def stuff ...
def get_urls(self):
urls = super(MenuOrderAdmin, self).get_urls()
my_urls = patterns("",
url(r"^export/$", export)
)
return my_urls + urls
Enjoy ;)
The easy and accepted way is to override the template.
If you don't want to mess with the Django templates, you could add a Media class to your admin and add some javascript to create the button although I think creating elements with javascript is a bit nasty and should be avoided.
Though other answers are entirely valid, I think it is important to note that it is absolutely not necessary to add a button to get such behavior. You can use admin actions, as you did for the make_published action.
This as the advantage of not requiring to override any template, and thus prevent from potential troubles when upgrading django version (as admin templates may change, and changes might not be "compatible" with the way you overrode it).
import csv
from django.http import HttpResponse
from django.utils import timezone
def export_as_csv(modeladmin, request, queryset):
opts = modeladmin.model._meta
filename = format(timezone.now(), "{app}_{model}-%Y%m%d_%H%M.csv").format(
app=opts.app_label, model=opts.model_name)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
writer = csv.writer(response)
field_names = [f.get_attname() for f in opts.concrete_fields]
writer.writerow(field_names)
for obj in queryset.only(*field_names):
writer.writerow([str(getattr(obj, f)) for f in field_names])
return response
Admin actions are made for this, adding a custom button is one step closer to "over-customization", which means it's probably time to write your own views.
The admin has many hooks for customization, but beware of trying to use those hooks exclusively. If you need to provide a more process-centric interface that abstracts away the implementation details of database tables and fields, then it’s probably time to write your own views.
Quote from the introduction paragraph of Django Admin's documentation