How to render Django forms.ChoiceField as Twitter Bootstrap dropdown - django

What is the most efficient way (in terms of programming/maintenance effort, elegance) to render a Django forms.ChoiceField as a Twitter Bootstrap dropdown using one of the django-bootstrap, django-bootstrap-form, django-bootstrap-toolkit, django-crispy-forms, etc apps? Is there explicit support for this use case in any of these apps?

Disclaimer I'm the lead developer of <a href="https://github.com/maraujop/django-crispy-forms/"django-crispy-forms (one of the apps mentioned).
I will try to explain how you do this with django-crispy-forms. You simply do in your template:
{% load crispy_forms_tags %}
{{ form|crispy }}
You can see this and more in django-crispy-forms docs. Your ChoiceField will be rendered as Bootstrap dropdown as you want.
Compared to django-bootstrap
First, a little bit of history. django-bootstrap was born after django-uni-form (the parent project from which django-crispy-forms evolved). At that time, django-uni-form was already doing Boostrap forms, but probably not in the best possible way (Bootstrap was supported by using an aditional contrib application). Thus, the author of django-bootstrap probably decided to go on its own.
Now, regarding Bootstrap support. django-bootstrap can also render forms but, instead of using a Django filter, it changes the base class of your form. So django-crispy-forms affects your templates while django-bootstrap affects your Python code.
Also, both django-crispy-forms and django-bootstrap let you do layouts. In django-bootstrap, layouts are in a Meta class within the form while in django-crispy-forms the layouts live in a subclass of FormHelper, which gives you decoupling.
django-bootstrap uses a tuple for defining a layout, while crispy-forms uses a subclass of Layout. This adds the possibility to reuse layouts, compose layouts easily, etc. Note that although crispy's encapsulation still has a list of fields inside, it adds a helpful and human-friendly API to programmatically manipulate the layout and I think enforces a good decoupling pattern.
From what I can see, layouts in crispy-forms are more powerful. It has a larger layout object collection, for example, prepended text, appended text, daterange and others are already supported while in django-boostrap these are in the TODO list.
crispy-forms has also an API for modifying layouts on the go and doing some hardcore programmatic layout building which is very nice.
crispy-forms also supports formsets of all kinds. It supports different CSS template packs, which means that if in the future the new kicking CSS pack is named 'chocolate', it will be very easy to create a new template pack for it and all your forms will be able to be rendered with 'chocolate' without code changes, just a simple setting variable.
crispy-forms also has attributes you can set in FormHelper that define nice extra functionaly you can easily turn on and off. You can also create your own custom attributes if you want.
Finally, django-crispy-forms (together with django-uni-form) has more than 67.000 downloads, which is quite good for a Django application. The project has almost 500 followers in Github, several big users, good testing coverage and several years of history and it's still actively maintained.
Compared to django-bootstrap-form
From what I can see django-bootstrap-form is only a filter for rendering a form with Bootstrap. That is something django-crispy-form covers while offering much, much more. The project was released on 21st August 2012 and looks to me like it's reinventing the wheel because several other apps cover already this use case.
Compared to django-bootstrap-toolkit
It's inspired by django-boostrap-form. From what I see in the docs, it also gives you a filter for rendering a form with Bootstrap. It apparently covers more Bootstrap stuff than forms, but I can't find more info in its docs. Last commit was 2 months ago.
I will insist that I'm obviously not the right person for a comparison that is not biased. That's why I've never written about this before. I could have published a blog post about this several times but I always dismissed the idea. However, as the fragmentation of form apps (and bootstrap-support apps) is growing, I thought this might be a good time to write down what I think.

Related

What are the ways to styling a Django Form?

I was working with Django forms, and to beautify the Django forms I came across widgets, and after learning it got to know that we can customize widgets in two ways:
Using widget instance or
Using widget class.
Later came across django-crispy and django-bootstrap that allow same beautification of the forms along with various other advantages over other.
But I was wondering, how many more such library / packages / apps are there, and is there any short of description for each, which might help me and others too.
Thanks
For simple design or not any extra validation in frontend bootstrap or crispy form is okay.
But if you want to take advantages of custom css js then widget is better option obviously.
I generally do:
create a form using css, js even if in bootstrap
Then pass the classes or id of the particular field in widget

django cms [aldryn newsblog] replace template for plugin

I need to replace same plugin template on different subpages - e.g. on frontpage I need specific slider template for latest articles, in detail article I need small list, on search result without images etc.
[note: everything about aldryn newsblog app - I don't mean my own plugin!]
*(something like custom template per plugin instance)
How to replace it ? Extending template is not quite what I need - inheritance is from bottom - from lower subtemplate to base.html - but that plugin have hardcoded lower template.
Tons of IF block in template is irrational then we think in MVC.
*( like here Render Django-CMS plugins differently on different splaceholders/templates )
Or maybe just write custom template with using hardcoded including plugins ? But using django cms placeholder editor is very useful and it'll be better to keep working in that way :///
So, I create front.html base template for frontpage,
put some plugins to placeholders - and need to replace subtemplates for this plugins only in this front.html and keep subtemplates for that plugin in other places - this is main goal.
It will be the best, when django cms / aldryn newsblog provide option "custom template" per plugin instance :|
( like this one http://www.ilian.io/django-cms-plugins-with-selectable-template/ )
If I understand your question correctly (it's late here), you need a way to override plugin templates on a plugin instance basis because hacking django templates is not the way to go (I agree).
Django CMS does allow you to override plugin templates on an instance basis.
As shown in http://docs.django-cms.org/en/develop/how_to/custom_plugins.html?highlight=get_render_template#the-simplest-plugin
In your CMSPluginBase subclass add the following:
def get_render_template(self, context, instance, placeholder):
# criteria goes here
return 'sometemplate.html'
As far as how to know which template to render when (criteria), you can do a few things.
Use the page's reverse id:
page = instance.page
templates = {
'homepage': 'plugin_home.html',
'about': 'plugin_about.html',
'contact': 'plugin_contact.html',
}
return templates[plugin.page.reverse_id]
This approach has a few drawbacks:
Relies on plugin being bound to a page. (plugins can live outside of pages)
Can only work with pages that have reverse id set and reverse ids
are unique per page which means you would have to list reverse id
for every page you want to change template for.
Use a page extension to set a category per page:
Checkout http://docs.django-cms.org/en/develop/how_to/extending_page_title.html
With this approach you can then set some sort of category to multiple pages and so you can target multiple pages in one shot like so:
page = instance.page
extension = get_page_extension(page) # Check out docs for this
templates = {
'category_1': 'plugin_category_1.html',
'category_2': 'plugin_category_2.html',
'category_3': 'plugin_category_3.html',
}
return templates[extension.category.name]
Pros:
Can target multiple pages in one shot
Cons:
Relies on plugin being bound to a page.
A bit more complex
Use a template context variable:
In your templates, depending on how you're rendering your plugins, you can
provide a context variable like so:
{% with category='category_1' %}
{% placeholder 'content' %}
{% endwith %}
or
{% with category='category_1' %}
{% render_plugin yourplugin %}
{% endwith %}
Then in your get_render_template method you can access this context variable and do the following:
# Use .get() to provide fallback
category = context['category']
templates = {
'category_1': 'plugin_category_1.html',
'category_2': 'plugin_category_2.html',
'category_3': 'plugin_category_3.html',
}
return templates[category]
Pros:
No extra models.
Can target multiple pages in one shot.
Cons:
The only one I can think of is these random {% with %} in
templates.
I completely missed the newblog part, so in order to override the newsblog plugins or any plugin, just subclass the plugin class you want to override and unregister the original and then register yours, make sure yours has the same class name.
Maybe you can make the whole template logic above into a mixin to use throughout your project.
I've always wanted to give Zinnia a look, but I'm too far into working with NewsBlog on a site right now to do it (and blogs have already been posted and whatnot). You can always just add a few extra placeholders in the template (it's not the most efficient looking thing ever, but it's no load on the framework if you add a placeholder and leave it blank), that way they aren't static, and then you can put whatever plugins you want to inside of them. You can customize each component in NewsBlog pretty easily by just adding whatever you want in the structure mode. Things get trickier when it comes to having multiple blogs that act differently, but even then, as long as you're not adding components into the static placeholders provided by NewsBlog (or as I so elegantly learned it, "don't put the stuff in the blocky-things with the pins next to them), you can create different namespace for the different blogs (either in the admin, under "Configs" in the NewsBlog section, or when creating a new page and hooking it to the NewsBlog app), and you can have different templates on different blogs.
EDIT: This is a really excellent resource for touching up NewBlog without throwing the baby out with the bathwater (after three months of learning DjangoCMS, I'm still finding myself referencing it for fine-tuning pieces of NewsBlog, and to refresh my grasp on templatetags and other things that are overwhelming and have quickly left my brain along the way): https://www.django-cms.org/en/blog/2016/02/16/build-a-website-without-knowing-python-django-part-two/
*I linked to part two, as the first part deals with how to initially setup a project, and I assumed it probably wasn't relevant. Then again, if you're using Aldryn, there are some useful bits in there that can extrapolate if you're having trouble with customizing the boilerplate (or other things you'd like to configure that an Aldryn setup handles for you -- which is super awesome most of the times, but when it's not super awesome, it's usually super frustrating :)

Components in Django

I have a latest news block on a page. It's a piece of markup in a template and some logic fetching the last n news in a view.
How can I make a reusable component of it (like some CMS have) which I can include in a template like this:
{% component "latest_news" "5" %}
for building a block with 5 last news.
Seems Inclusion tags is quite good for this purpose, but I wonder may be is there some build-in component-like feature in Django?
The closest to CMS's components functionality in Django is Inclusion tags
In 2021, I have come across the following projects:
https://pypi.org/project/django-render-partial/
https://pypi.org/project/django-components/
I have used django-render-partial pretty extensively, and I like that the interface allows your partials to be used in templates, or hooked directly up to a urls.py.
django-components looks pretty cool, because it allows you to package CSS and JS files with the use of a Media class (similarly to Django forms), but it fractures the "everything is a view" pattern provided by django-render-partial.
I used django_components which saved me a lot of pain, it supports creating reusable components with dynamic components name, and it also allows passing HTML fragments to the components.

Writing translatable static web pages using Django

I am a bit confused on the best way to handle this problem:
My web site needs read-only static web pages (typically the About part of a web site) with 2 simple constraints:
they need to be translated
they need to have flexible layout: to incorporate base headers/footers, floating images and/or tables, and non-interactive elements (like a bootstrap carousel).
Several solutions that I have thought about:
I can of course directly write HTML files but the translation part will be awkward (a lot of <h1>, <ul>, <li> and <p> which are of no interest to the translator).
I can use Django flatpages with some markup languages but I lose a lot of flexibility (for instance template tags are not recognized)
Use generators like Hyde, but it seems quite overkill for my needs and internationalization seems a bit difficult
Does someone have other propositions that I can look into ?
Thanks !
Use django-cms, it has a Page model that can be translated and has a very smart plugin system to add many content-types into every page.
I use it a lot and it's very easy and yet powerful
For completeness and fairness, here's a full list of available CMS packages for Django.
for a much simpler solution, I would create a model called "Page" with lets say title and text fields.
The title and the text fields I would register to django-modeltranslation which will handle the translation issue.
For the text field i would use TinyMCE which let you insert basically any HTML you want so you can do whatever you need.

Twitter bootstrap and crispy forms confusion

I decided that I wanted to use twitter bootstrap for a potential website I want to make. However, I am still learning web development. I was wondering if someone could give me and explanation of what Crispy forms has to offer. I've been reading and I believe that it has twitter bootstrap embedded in it? I was wondering which would be a better choice to pick. This might be a bad question to ask but I'm quite confused. Are there pros and cons to picking either?
Twitter bootstrap is something completely different than crispy-forms:
Twitter bootstrap is a CSS and Javascript presentation framework. You can use it to generate your html pages from any framework, not just Django! You can use it to define how your html will be layout in a grid and also it has styles for a number of html components.
Crispy-forms is a Django application that can be used to create better layouts for forms. What it does is that you can define programatically how you want your form to be rendered (instead of doing it in the template with html). You should use it if you want to have really nice looking forms without too much hassle.
The only relation between the two is that crispy-forms actually can render your form using bootstrap layout, meaning that the styles and classes etc of your rendered html form will be following the concepts of the bootstrap framework. I am copying from here http://django-crispy-forms.readthedocs.org/en/latest/install.html#template-packs:
Since version 1.1.0 of django-crispy-forms has built-in support for different CSS frameworks, known as template packs within django-crispy-forms:
* bootstrap Bootstrap is crispy-forms’s default template pack, version 2 of the popular simple and flexible HTML, CSS, and Javascript for user interfaces from Twitter.
* bootstrap3 Twitter Bootstrap version 3.
* uni-form Uni-form is a nice looking, well structured, highly customizable, accessible and usable forms.
* foundation Foundation In creators words “The most advanced responsive front-end framework in the world”. This template pack is externally available through crispy-forms-foundation
So crispy-forms can use a bootstrap mode to render your forms -- but you have to be already using bootstrap in your django templates for this to appear properly!