django-easy-select2 Select2Multiple widget doesn't render - python

The installation page looked simple enough. I installed it, added easy_select2 in INSTALLED_APPS in the settings, ran collectstatic, and then had this in my form:
from easy_select2 import Select2Multiple
# from django_select2 import forms as select2_forms
class LeadForm(forms.Form):
email = forms.CharField(max_length=100)
overseas_company = forms.MultipleChoiceField(
choices=countries,
label='Do you have any companies overseas and where?',
widget=Select2Multiple()
)
But it still renders as if I had done nothing at all. I tried django_select2 as well, and it didn't work either, so I must be doing something wrong Select2 wise.
I tried looking at the HTTP request log. Merely enabling easy_select2 doesn't make the template request the jQuery/select2 js files that are needed for the Select2 widget to function. Is this the problem? But the tutorial never said I had to add anything to any existing templates.

I had the same problem too.
You have to add {{ form.media }} in the head section of your template for django to make it work.
source: http://do-it-big.com/getting-django-easy-select2-to-include-jquery-and-friends/

Related

Django CMS how to create nested plugins programatically

I am writing a migration script to parse an old html website into Django CMS pages.
The thing I need is to understand on how to nest plugins programatically.
In particular case I need to have html < a> tags converted into CMS LinkPlugin objects, nested inside text that is edited by standard ckeditor TextPlugin of Django-CMS.
How to programmatically nest plugins inside other plugins of Django CMS. In my case I need to nest a CMS Link plugin inside of the TextPlugin in the text.
I know on how to parse text. I do not understand on how to do it from nested CMS plugins perspective?
I can not interconnect the Link CMS plugin object instance and CMSPlugin object instance that I insert into the ancestor TextPlugin.
More context:
Note I really know how to do this from UI perspective. I need to emulate this in a script.
I have dumped the database into JSON and noticed there are certain things there.
First I have a CMSPlugin class instance that is placed into a page placeholder. (Sotle this part from placeholderadmin.py of the CMS)
position = CMSPlugin.objects.filter(language=lang, parent=parent).count()
plugin = CMSPlugin(
language='en',
position=position,
plugin_type=plugin_type,
placeholder=placeholder,
)
plugin.insert_at(parent, position='last-child', save=False)
plugin.save()
# ?????
plugin.link = Link(
name='Link text',
page_link=target_page,
placeholder=placeholder,
)
plugin.save()
This creates a nested plugin in a proper placeholder and attaches it into a text plugin. However it is added with a blank LinkPlugin instance. I'm later creating an instance of a Link plugin in the CMS.
The thing is I do not know on how to do this properly.
From UI perspective the CMS plugin is added nested but contains no real plugin instance. SO the Admin plugins tree for that placeholder is rendered with empty Link plugins.
CMSPlugins are added Link < Empty>.
I can edit this created Link plugin through admin and add a text and target link. How to do this programatically. E.g. inside of a script? Script must do 1000-s of pages so I can not do it manually
Sorry just to be consistent on this. This is far more complicated in logic then it seems.
I did an article on this.
Django CMS Adding plugins inside plugins programmatically
In general the solution is to mimic the CMS way of doing this.
# Getting an site admin instance
admin_site = AdminSite()
instance, plugin_admin = plugin.get_plugin_instance(admin_site)
plugin_admin.cms_plugin_instance = plugin
plugin_admin.placeholder = plugin.placeholder
# Triggering the Django Admin add view with our request.
# That's how Django-CMS does this action itself.
response = plugin_admin.add_view(request)
Look for the full snippet in article. Hope this helps someone with similar problems.
To add nested plugins you need to do this:
add_plugin(
placeholder=placeholder,
plugin_type='TextPlugin',
language=translation.get_language(),
)
target = placeholder.get_plugins().get(plugin_type='TextPlugin')
add_plugin(
placeholder=placeholder, #same placeholder as the parent plugin
plugin_type='LinkPlugin',
language=translation.get_language(),
target=target, #the parent plugin
#here comes the params from the selected plugin
name='Google',
url='http://www.google.com'
)
This also works with custom plugins.
Did you tried to save Link plugin that you've created?
plugin.link = Link(
name='Link text',
page_link=target_page,
placeholder=placeholder,
)
maybe try to add
plugin.link.save()
I hope that is the case.
To create nested plugins in your cms_plugins.py file
from .models import ParentPlugin, ChildPlugin
#plugin_pool.register_plugin
class ParentCMSPlugin(CMSPluginBase):
render_template = 'parent.html'
name = 'Parent'
model = ParentPlugin
allow_children = True # This enables the parent plugin to accept child plugins
# You can also specify a list of plugins that are accepted as children,
# or leave it away completely to accept all
# child_classes = ['ChildCMSPlugin']
def render(self, context, instance, placeholder):
context = super().render(context, instance, placeholder)
return context
#plugin_pool.register_plugin
class ChildCMSPlugin(CMSPluginBase):
render_template = 'child.html'
name = 'Child'
model = ChildPlugin
require_parent = True # Is it required that this plugin is a child of another plugin?
# You can also specify a list of plugins that are accepted as parents,
# or leave it away completely to accept all
# parent_classes = ['ParentCMSPlugin']
def render(self, context, instance, placeholder):
context = super(ChildCMSPlugin, self).render(context, instance, placeholder)
return context
In your plugin template file of parent plugin
{% load cms_tags %}
<div class="plugin parent">
{% for plugin in instance.child_plugin_instances %}
{% render_plugin plugin %}
{% endfor %}
</div>
For detailed documentation, go through
https://docs.django-cms.org/en/latest/how_to/custom_plugins.html#nested-plugins

url template tage variable not being parsed django

I am trying to dynamically generate links in my template of the form ..../hub/username/ but am always getting back only ..../hub for some reason. I have read through the docs several times and it seems very clear what to do, but I am just making some mistake somewhere I suppose!
Please Help!
I have in my urls:
urlpatterns = patterns(
'',
url(r'^hub/(.+)/$', 'hub.views.hub_view', name="hub"),
...
...
)
I have in my template:
<li><a id="todoMenuButton" href="{% url 'hub' user.username %}">ToDo</a></li>
template context preprocessors is enabled in my settings:
TEMPLATE_CONTEXT_PROESSORS = (
'django.core.context_processors.request',
)
Thanks!
Instead of adding the request context processor to the default set, you've overwritten the defaults with that single one. That means there is no user variable defined in the context. You could use request.user instead, but it would be better to fix your seeing as there are other useful processors you are missing out on (eg debug).
It was a simple mistake, I was using the todo button instead of the hub button :/
Sorry!
Thanks!

How to add button next to Add User button in Django Admin Site

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

Django: Programmatically determine path to an admin page?

If I have the admin module enabled for a certain model, is there a way to determine what the full URL will be for the page to create a new instance of that model?
What I'm looking for is something like this following:
"Please <a href='%s'>create</a> some Foo models" % Foo.AdminCreateUrl
Update: To clarify, this needs to be done on the backend rather than on the templating layer.
This is what I'm currently doing:
DisabledMessage = "No foos exist. Please <a href='%s'>create</a> some before assigning bars." \
% urlresolvers.reverse('admin:app_foo_add')
This does not work. I get the following error message:
ImproperlyConfigured at
/admin/bar/bar/add/
The included urlconf mysite.urls doesn't
have any patterns in it
What am I doing wrong?
First, read this. The admin site must be properly activated.
http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#overview
Second, read this. This is how the admin URI names work.
http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#admin-reverse-urls
I think you can use the {% url %} template tag.
Please create some Foo models
Reversing admin urls.

How do I add data to an existing model in Django?

Currently, I am writing up a bit of a product-based CMS as my first project.
Here is my question. How can I add additional data (products) to my Product model?
I have added '/admin/products/add' to my urls.py, but I don't really know where to go from there. How would i build both my view and my template? Please keep in mind that I don't really know all that much Python, and i am very new to Django
How can I do this all without using this existing django admin interface.
You will want to wire your URL to the Django create_object generic view, and pass it either "model" (the model you want to create) or "form_class" (a customized ModelForm class). There are a number of other arguments you can also pass to override default behaviors.
Sample URLconf for the simplest case:
from django.conf.urls.defaults import *
from django.views.generic.create_update import create_object
from my_products_app.models import Product
urlpatterns = patterns('',
url(r'^admin/products/add/$', create_object, {'model': Product}))
Your template will get the context variable "form", which you just need to wrap in a <form> tag and add a submit button. The simplest working template (by default should go in "my_products_app/product_form.html"):
<form action="." method="POST">
{{ form }}
<input type="submit" name="submit" value="add">
</form>
Note that your Product model must have a get_absolute_url method, or else you must pass in the post_save_redirect parameter to the view. Otherwise it won't know where to redirect to after save.
This topic is covered in Django tutorials.
Follow the Django tutorial for setting up the "admin" part of an application. This will allow you to modify your database.
Django Admin Setup
Alternatively, you can just connect directly to the database using the standard tools for whatever database type you are using.

Categories

Resources