Is there a way to do this inside a django template? (in pseudo code)
{% if perms.tasks.can_play_{{football}} %}
I can't think of a way to do this besides using ugly repeating code
Related
I have an issue on my Django project. I have a situation as follows:
{% for subObject in mainObject.subObjects.all %}
This works nice, every subObject gets iterated nicely. What I want now is that I print a subset of the objects, something like:
{% for subObject in mainObject.subobjects.filter(someField=someValue) %}
So far I have searched solutions about the error I get:
Could not parse the remainder: '(someField=someValue)'
but did not find a solution about how the line should be different when a filter is used. I want to tweak just the template.html file, thus I don't want to make the change on views.py file (where everything supposedly would work nicely).
How to achieve this?
Following #Yuji'Tomira'Tomita's comment..
Don't put too much logic into the template, quote from django docs:
Philosophy
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.
Better define the queryset in the view and pass to the template:
view:
def my_view(request):
...
my_objects = mainObject.subobjects.filter(someField=someValue)
return render(request, 'mytemplate.html', {'my_objects': my_objects})
template:
{% for subObject in my_objects %}
...
{% endfor %}
Hope that helps.
I'm new to Django but I've been really enjoying it. But occasionally I seem to run into places where I just don't seem to get things correct. So, I'm asking for some help and guidance.
I'm trying to extend the object-tools for one of my models so I can have a Print button next to History.
My templates is as follows:
project/app/templates/admin/
I'm successfully extending base_site.html with no issues.
project/app/templates/admin/base_site.html
However, when I add change_form.html like so:
project/app/templates/admin/change_form.html
With the following:
{% extends 'admin/change_form.html' %}
{% block object-tools %}
One
Two
{% endblock %}
I get an exception: maximum recursion depth exceeded while calling a Python object
This seems like I'm missing something quite basic.
Things that I've tried:
Many variations of the {% block %}
extending base_site, base etc ...
adding /model as part of the path (project/app/templates/admin/model/change_form.html)
I'm confused and unsuccessful.
P.S.: I'm also using a bootstrap theme from here http://riccardo.forina.me/bootstrap-your-django-admin-in-3-minutes/ but for the purposes of this problem I'm currently not using it.
The problem is that admin/change_form.html in your {% extend %} block is getting resolved as project/app/templates/admin/change_form.html.
One solution is to create a subdirectory of templates named for your app - possibly project/templates/admin/app/change_form.html.
In order to override one or more of them, first create an admin directory in your project’s templates directory. This can be any of the directories you specified in TEMPLATE_DIRS.
Within this admin directory, create sub-directories named after your app.
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template
That's because you're extending the template with itself. What I do is put my custom admin templates in templates/admin. Then in that same folder I symlink to the django admin folder (templates/admin/admin).
So my extends looks like:
{% extends 'admin/admin/change_form.html' %}
Make sure you also override index.html if you want to go down that path.
The best way to do this that I have found is to use '..' to go up a couple of directories, then go back down into directories that should only be found in the Django code base.
As the Django templates are in something like "django/contrib/admin/templates/admin", I found that this worked me:
{% extends "../../admin/templates/admin/change_form.html" %}
If that still causes a clash with some other structure you have, you could go further:
{% extends "../../../contrib/admin/templates/admin/change_form.html" %}
or even:
{% extends "../../../../django/contrib/admin/templates/admin/change_form.html" %}
Although it is a little hacky, at least by doing the above you don't have to use some other technique that involves copying the django source or setting up a symlink.
When incorporating a third-party django app, I typically want it to be integrated aesthetically with the rest of my django project. While this is typically a matter of overriding the apps 'base.html' (if that), we all structure our templates a little differently, so incompatibilities often arise. For instance, suppose an app defines {% block footer %} and and makes use of it for a variety of things throughout its templates. If I am already using {% block footer %} for, say, a nav bar or copyright info, I don't want the app's templates to override my block.
A simpler, related case would be using different block names for the same thing. For instance, {% block extra-head %} versus {% block extrahead %}.
What's the best way of resolving these sorts of situations? Ideally, it would be nice to remap blocks, so you could do things like "put the child's {% block footer %} in the parent's {% block content-footer %}". Is there any way to get close to that? Or is the only solution to simply override every conflicting template?
First, the html inheritance should go:
my-sitebase.html
|-- app-base.html
|-- app-foo-template.html
I think this is what you meant, but the wording was a bit ambiguous. You might be able to just edit the app-base.html.
Second, a reusable app that overrides something like {% block footer %} is almost willfully causing trouble for anyone who uses it -- you should flag that in the provider's issue tracker.
If the app does do anything with {% block footer %} that should be done in the app-base.html area so you only have to change it once when integrating it with your site.
Finally, a recursive find-replace is actually very little effort. If you don't use an IDE that allows this, Text-Crawler is free, lightning fast, and a good non-IDE solution.
There have been a couple of attempts to create a standard inheritance pattern, I put together one that I like for the templates at djangoslingshot.com and I've seen one other -- but so far there hasn't been any coalescence around a standard. Likely because find-replace is actually a very low cost for the benefit of being able to do exactly what you want without someone else's rules getting in your way.
I've been implementing caching in my django application, and used per view caching via the cache API and template fragment caching.
On some of my pages I use a custom django template tag, this tag is provided via a third party developer, it takes some arguments in its template tags, and then make a request to a remote server, gets the response back over XML, and then renders the result in my page.
Great - I thought I could easily cache this using fragment caching, so I :
{% load cache %}
{% cache 500 request.user.username %}
{% load third party custom tags %}
{% expensive custom tag set that gets stuff from a third party server via xml %}
{{ some.stuff}}
{% endcache %}
Trouble is no matter what I do, the requests still get fired off to that remote server, it seems Django doesn't like to cache these custom template tags. I know memcached is working great, for other views and templates it all works just fine. Am I doing something that is incompatible with the fragment caching? Is there a way round it?
If the template fragment you're trying to cache can't be pickled, memcached won't be able to store it and will raise an exception. From what I can gather, exceptions generated when rendering Django templates are suppressed. Since your custom tag is doing HTTP requests, maybe socket objects (which can't be pickled) are getting stored to the template fragment somehow.
If this is the case, the only way around it I can think of would be to modify the custom tag to get rid of any leftover socket objects.
Have you tried to use a different name for the cache fragment? There could be a problem with using request.user.username for a couple of reasons:
If a user is not signed in,
request.user.username could be empty,
resulting in a non-named cache
fragment
If a user is signed in, this will
call the 3rd party template tag at
least once for each user every 3
mintues
Maybe it's worth trying to rename the cache fragment name to test:
{% cache 500 customxml %}
I'd also try loading of the 3rd party template tag outside the cache tag like so:
{% load cache third_party_custom_tags %}
{% cache 500 request.user.username %}
{% expensive custom tag set that gets stuff from a third party server via xml %}
{{ some.stuff}}
{% endcache %}
What I'm not sure of is if the cache framework caches the results of a template tag. If that doesn't work, I'd take a look at what the template tag is doing under the hood and re-implement the template tag using Django's low-level cache.
I think the problem is the custom tag, as you suggested.
I disagree that the request.user.username is a problem, as the documentation for the subject actually gives that as an example, and I have used it with internal caching (number of posts, for instance), in testing, and it worked fine.
The low level cache is potentially useful, but I would take a look at your custom tag to see what wouldn't be caching. Without the code it's hard to guess, but my guess would be something like the time, or some other variable, is being returned whic his causing it to force an update (if the XML pulls any data that changes Django may force an update, depending on other settings). I've had mixed results with Django's caching, so I would have a look at your XML feed(s) to see if it's causing anything to stop caching.
I don't think this has anything to do with the custom tag.
We endded up rewriting the Django caching tag because we needed more control than was possible with the one that was supplied. You might make a copy of it yourself and stick some debugging print statements into it. In particular, check the filename (assuming you are caching to files) and see what is being generated. It could be that it is changing when it shouldn't (for some unknown reason) and that would mean that it is always needing to re-render then enclosed block.
Look in django/templatetags/cache.py. It's only 63 lines of code.
I'm having an issue with django templates at the moment. I have 3 template files basically:
Base
story_list
story_detail
Story_list and _detail extend Base, and that works perfectly fine. However, list and detail share some code that extend the base template for my sidebar. I'm basically repeating a chunk of code in both templates, and the programmer in me says that's just wrong. There has to be a better way, I'm sure of it. I've tried includes, however I have in the included file:
{% block item %}
content stuff
{% endblock %}
for about 3 blocks. The problem is that none of that is being picked up/rendered. If I include the file in a block section that extends base, then it dumps everything properly, but if I don't include it in a block, I get nothing. Is SSI the way to go? I toyed with that, but that didn't seem to work properly either. Any help is appreciated.
Generally, using includes is not the answer with Django templates. Let me answer your question on several fronts.
First, let me address the sidebar.
Are nearly all the common pages going to be using that sidebar? Put it in Base. Don't override those sidebar blocks (i.e. don't write them at all in your Story_* templates).
Is this sidebar unique to the Story_* templates? Make another template called, say, Story_base and extend that. This is akin to making an abstract superclass in Java. (Answer was in my head, but wording was mercilessly ripped off from jpwatts.)
Next, let me address template inheritance. Say you have a template named Story_list that extends Base. At this point, after just putting {% extends "Base" %}, Story_list is exactly Base. Anything else you put in Story_list is ignored, because the template is already complete. The only thing you can do now is override blocks that have been defined in Base.
Finally, let me address includes. Try to always avoid them. Other templating engines, such as PHP, seem to encourage using includes. However, this can lead to less manageable templates in the long run. It's slightly harder to glance at an included snippet and immediately ascertain its place in your template hierarchy. They're also harder to refactor into the template hierarchy, especially if you include them at several levels (once in Base, twice in Story_base, once in some of the Story_*, etc.).
If there is common code between the story templates that isn't needed site-wide, I'd create a story_base (extending the original base) and have my story templates extend that.
You have an {% include %} tag for this.
{% include xxx.html %}
This tag works.
An alternative way is to use filter. Filter calls a function for rendering, template can be used while rendering.