How to display local-memory cache in Django Templates? - python

I set the local-memory cache "message" as shown below:
from django.core.cache import cache
cache.set("message", "success", 300)
Then, I tried to display it in the Django Template "index.html" as shown below:
# "index.html"
{{ cache.get.message }}
But, "success" is not displayed.
So, are there any ways to display the local-memory cache in Django Templates?

Django's template system is not simply Python embedded into HTML. It has a few wrappers built-in for looping, conditionally rendering, etc.
From Django Docs:
If you have a background in programming, or if you’re used to languages which mix programming code directly into HTML, you’ll want to bear in mind that the Django template system is not simply Python embedded into HTML. This is by design: the template system is meant to express presentation, not program logic.
In order to get a value from the cache you need to run cache.get('key_name') which is not allowed from within a template.
You can retrieve the value you want to display in the view and pass it to its template directly.

Related

How to enable django admin sidebar navigation in a custom view?

I have a view inheriting from LoginRequiredMixin, TemplateView, which renders some data using the admin/base_site.html template as the base. I treat it as a part of the admin interface, so it requires an administrator login. I'd like to make this view a little bit more a part of the Django admin interface by enabling the standard sidebar navigation on the left-hand side.
Note that I don't have a custom ModelAdmin definition anywhere, I simply render the template at some predefined URL. There are no models used in the interface either, it parses and displays data from database-unrelated sources.
Currently, I just build the required context data manually, e.g.:
data = super().get_context_data(**kwargs)
data.update(**{
"is_popup": False,
"site_header": None,
"is_nav_sidebar_enabled": True,
"has_permission": True,
"title": "My title",
"subtitle": None,
"site_url": None,
"available_apps": []
})
The sidebar is visible, but displays an error message:
Adding an app to available_apps ("available_apps": ["my_app"]) doesn't help either:
So my question is - how do I do that? Is there a class I can inherit from to achieve this behaviour? Or a method I can call to get all required context data for base_site.html? Or perhaps I should insert some information in my template? Perhaps I need an AdminSite object, or can somehow call methods of the default one?
By accident I noticed there is a DefaultAdminSite object in django.contrib.admin.sites, and it's instantiated as site. Therefore, in my case, simply using site is sufficient.
from django.contrib.admin import AdminSite
from django.contrib.admin.sites import site
admin_site: AdminSite = site
data.update(**admin_site.each_context(self.request))
Furthermore, turns out I can just use the apps in case importing site would be an issue, just like DefaultAdminSite does it:
AdminSiteClass = import_string(apps.get_app_config("admin").default_site)
self._wrapped = AdminSiteClass()
The app_list.html template which is included in your base template requires a context variable available_apps with a structure as described here.
As you probably won't be able to make this include work properly with your app you could also override the {% block nav-sidebar %} in your base template and provide some HTML that fits your use-case.
But after all it's probably not such a good idea to reuse templates which are made for a different app (admin) with your app because it's difficult to predict how they will behave, what their requirements are and beyond this maintainance in the long term will also be a problem as they might change with future Django versions.
You have to include django admin's default context variables used in the template. This can be done by calling each_context function:
data.update(self.admin_site.each_context(request))
I also have custom admin views and templates in my projects and this works well for me.

Too many templates in Django

I am learning Django and I programming a CRUD for various objects. Currently I need to generate three templates per object: one for creation, one for update and one for a list. Look at how many templates I got in the picture.
The process is becoming painful.
What I am doing wrong and how to correct it?
Thanks.
From your comment:
The problem is that If I need to make a change, for example, add a new button, I have to make it in all the templates.
That sounds wrong. Either a button belong to one type of thing and then it should only exist in that template, or it should be on every page and then it should be in the base template.
You can make one template with your basic page layout (including such buttons), and have "blocks" in them that are then filled out by each template that extends the base template.
See the Django documentation about template inheritance.
Also, I think that in most cases the "create" and "update" pages are going to be extremely similar; usually they use the same template, one with data already filled in, the other without.
You could have a base template, then a generic list template and a generic edit/create template, with templates for each type of thing extending the list and the edit templates to fill in only the relevant fields.
Also, maybe you use HTML that is close enough to what the Django forms can render themselves. Then as long as you call the edit/create form the same in each of your views (like "form"), the template can just render the form and they can all use the same template.
If you're building a big web-app then this is normal for templates to be more.
Heavy (big) web-app means = more templates + more code + more time + more features

Best Django practise - when to use views and when to use tags

I'm in the process of delving into Django into a little more depth - and I now have certain blocks around my website which are recycled, but not necessarily suited to a being placed in base.html and then sprinkled with {% extends /root/to/base.html %}.
So, I have a bespoke widget I have created which is utilised on certain pages but in different configurations, is it best to register and inclusion tag and reference the template you want to accompany those stored variables and arrays/lists/dictionaries etc..
For me it seems easier to define tags and then dot these around where I need them and just make edits to the template that is registered with that tag method? But is this the accepted Django standard?
In Django
a "view" is a callable that is responsible for handling a request and returning a response,
a template tag is a piece of code that will be executed in the context of rendering a template and will either push something in the template's context or render some text or markup.
Oranges and apples, really, and it should be quite clear when you want a view and when you want a template tag.
And yes, using inclusion tags (or a full-blown custom tag using a template to render some data) is "an accepted Django standard" - actually that's exactly what template tags are for.

Django CMS simple placeholders outside of cms

I have a fully developed Django app and decided to add DjangoCMS to give a content developers a quick way to prototype landing pages etc. It now lives under myurl.com/cms and works quite well. The guys can create new pages, choose a template and add plugins there.
When i saw the placeholder template tag I immediately thought about placing it all over the project, outside the cms, everywhere I want the product team to be able to quickly add and change content. I don't want them to create a new page for this from the cms because maybe the site has complex functionality which is only used once in this context (i.e. the search page).
So basically I expect to have static placeholders that I can place in the html part of the page using the cms plugins template tags.
I already found Placeholders outside the CMS in the DjangoCMS docs.
But for this to work I have to grab the related placeholder object for every view that renders a page, which would increase the amount of work to "quickly add a placeholder for this text" considerably.
Is there an easy way to do this? I kind of expect to not be the first to have that issue.
There's three types of placeholders:
Page placeholders - Declared using {% placeholder %}. These can only be used inside a cms page.
Static placeholders - Declared using {% static_placeholder %}. Not bound to pages or objects.
App placeholder - Declared in your models.py using PlaceholderField and rendered in template using {% render_placeholder %}
The rule of thumb is, if you're rendering a cms page, use a page placeholder, otherwise depending on your use-case use a static placeholder.

Building a generic block-based CMS with Django

A designer recently handed me designs for a site I'm building for a client. They're great designs but I'm really scratching my head as to how I'm going to implement it on the site.
The content can very easily be broken down into blocks or chunks of data where I could allocate a textarea for text input, a couple of charfields for link-buttons, etc and sequentially render them out to the page.
The problem (eg why I'm not just pulling in Django-CMS et al) is the blocks are quite unique from each other. There are perhaps 20 different models that I would build for each block type. Rather than hack around a pre-fab CMS, I'd like to build a Page model and then just have an M2M that links to an ordered list of subclasses of my abstract Block class. I hope I'm not losing you.
I don't understand how I can do this. These questions spring to mind:
Is there a simple CMS that does all of this already? Am I wasting my time trying to figure out the physics?
My Blocks subclasses will technically be different type. Do I need generics for a M2M-through class to link to them? Is so, how do I do that?
How do I render x different forms in an inline admin context? (I'd like to have the page form with a list of the Blocks underneath)
How can the user specify the type of Block in the inline control?
Edit: Or, alternatively, what about a templatetag-based CMS?
I'm thinking of something like plonking this in my template:
{% editable 'unique_id' 'content-type' %}
A further example:
{% editable 'home-intro' 'text' %}
Then I could just stick these around the templates I want to be editable, in the way I want them to be editable and when logged in the client would see "Edit text", "Edit link", "Edit image" links which simply popped up the right field.
This would make things more locked down but the layout needs to remain solid (and the client knows nothing about HTML/CSS) so it's one or other of these methods IMO.
Couldn't you implement your 'Blocks' as Django CMS Plugins? Then each page is just constructed from a number of plugins.
Each plugin has an admin form which gets the specifics for itself, and then the page template renders the plugin as you want it.
If you look at the first page of the django-cms demo:
https://www.django-cms.org/en/tour-demo/
you'll see in (1) a highlighted plugin block - in this case a formatted text block that is edited with TinyMCE or similar. You can define your own plugins and add them to pages.
last month I published an article (for review) on how tho build a basic CMS for Jinja. This's templating language does not dffer very much from Django, which I have been using before.
You can find it here. It uses template inheritance to fill the content blocks.
https://codereview.stackexchange.com/questions/5965/review-request-jinja-cms-for-energiekantoor-nl-on-google-app-engine
Or type in Google : Jinja CMS

Categories

Resources