Add button in the admin interface - django

I needed to add a button in the admin interface just before an Inline. What I've made is add the following in change_form:
{% block after_field_sets %}
<input type="button" value="Add contract" onClick=" window.location.href='../../contract/add/' ">
{% endblock %}
But...now the button is shown in every model page of the admin interface not just in the page of the Inline.
Any suggestion?

You can override the template for desired model only. So template should be templates/admin/my_app/my_model/change_form.html instead of simple templates/admin/change_form.html

Related

Data base saving & Redirection issue using django

I have an issue, I do not know why it is happening and how to solve it;
My app ask a user to create a project and is redirect directly to the project detail page. On that detail page if a team_id is empty I ask the user to create a team and when the team is created the user is redirected again to the project detail page to now be able to populate his team.
I used the code {% if Project.team_id == None %} when the user is redirected after creating his team but it is not working .. could you please help ? It is like before the redirection the new team is not saved in the Db ..
my html:
{% extends 'base.html' %}
{% block body %}
<div class="container">
<div class="jumbotron">
<h2>Welcome to your Project {{ project.name }} Detail page</h2>
</div>
{% if Project.team_id == None %}
<div class="invite-team">
<div class="jumbotron">
<div class="jumbo-text">
<h3>It is time to link a team to your project now create a new team and add team members</h3>
</div>
<div class="jumbo-button">
<span class="glyphicon glyphicon-plus"></span> Create a new team
</div>
</div>
{% else %}
<div class="invite-teammembers">
<div class="jumbotron">
<div class="jumbo-text">
<h3>The team {{ project.team_id }} has beed created, we now need to add TeamMembers</h3>
</div>
<div class="jumbo-button">
<span class="glyphicon glyphicon-plus"></span> Create a new team
</div>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock%}
Looking at your surrounding code, you are using project as the container of your project. However, in your statement you are using Project (first character uppercase). Changing Project to project might help.
Your comment question:
what do you mean "Looking at your surrounding code, you are using project as the container of your project". my model Project is with a capital letter why now it is without ?
With looking at the surrounding code I mean that I literally looked at your code how you are using the variables in the other parts of your code. I am not sure if you are using CBV (class based views) or FBV (function based views).
With CBV the object is added to the context with the name defined in:
DetailView:81
or ListView:104
You can override the context object name by using the context_object_name in the View class
If you are using FBV, you have added it to the context manually as something like:
return render(request, 'myapp/template.html', {
'project': <project_query_or_variable>,
})

Plugin with editable link element

While implementing a Django CMS site, I’m a little stuck on link management (internal or external). In my project I have a specific box plugin the operator is to use quite often. I added screenshots of edit dialog and box rendering at the end of the question.
The edit dialog is nice, but right now the button is just a char field. So the link selection, either to a page within Django CMS or to an external URL, is missing. I looked for a link field, but until now I am lost.
How to add the feature to let the operator select an internal or external link ?
The plugin consists of these parts:
models.py
from django.db import models
from cms.models.pluginmodel import CMSPlugin
from djangocms_text_ckeditor.fields import HTMLField
class CardPlugin(CMSPlugin):
title = models.CharField(max_length=256,default='')
description = HTMLField(configuration='CKEDITOR_SETTINGS',
default='')
button = models.CharField(max_length=256,default='')
def __str__(self):
return str(self.title)
cms_plugins.py
class CardCMSPlugin(CMSPluginBase):
model = CardPlugin
name = 'Card'
render_template = "card-default.html"
card-default.html
{% load cms_tags %}
<section class="card card--primary-light">
<div class="card__inner">
<div class="card__content">
<div class="card__text">
<h2 class="card__title">
{{ instance.title }}
</h2>
<p class="card__description">
{{ instance.description }}
</p>
</div>
{% if instance.button %}
<div class="card__buttons">
{{ instance.button }}
</div>
{% endif %}
</div>
</div>
</section>
the rendered box
The plugin edit dialog looks like this:
I'd suggest looking at adding the djangocms-link plugin as a child plugin. It's a very good plugin to link to internal CMS pages or external addresses. That way you could drop the button field from your model, and instead render the child plugins in your template.
The docs on nested plugins would be a good read.
Your plugin definition would become something like this;
class ParentCMSPlugin(CMSPluginBase):
render_template = 'parent.html'
name = 'Parent'
model = ParentPlugin
allow_children = True
child_classes = ['LinkPlugin']
To render child plugins you'd then do this with your template;
{% load cms_tags %}
<section class="card card--primary-light">
<div class="card__inner">
<div class="card__content">
<div class="card__text">
<h2 class="card__title">
{{ instance.title }}
</h2>
<p class="card__description">
{{ instance.description }}
</p>
</div>
{% for plugin in instance.child_plugin_instances %}
{% render_plugin plugin %}
{% endfor %}
</div>
</div>
</section>
And that would use the default render template for the child plugin. If the default didn't match the styling etc, you could handle the rendering in the template instead of using render_plugin or subclass the LinkPlugin to work how you want, or extend it's attributes etc.
Some further consideration should do to dropping your description field in favour of also using the TextPlugin as a child, because the CMS text plugin can nest plugins within itself and is something I'd always use over an HTMLField.
Further still, if you're developing applications hooked in to CMS, take a look at PlaceholderFields which allow you to create placeholders in your own models to hold & use the CMS plugins that you can use in CMS pages. That gets really good for things like news apps or blog style content etc.

how to add css class to radio button in django template

I am trying to do the following with django widget tweaks:
{{ form.gender.0.tag|attr:"class:radio_1" }}
I get the error:
'SafeText' object has no attribute 'as_widget'
What am I doing wrong?
Initialize your RadioButton like this:
CHOICES=[('option1','option1'),
('option2','option2')]
radio = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect(attrs={'class': 'radio_1'}))
and the generated HTML-Code will look like this:
<input type="radio" class="radio_1" ... />
You may have figured out already how to apply CSS to radio buttons in Django template but in case someone is in the same situation, here's a code straight from the docs:
<fieldset>
<legend>{{ myform.beatles.label }}</legend>
{% for radio in myform.beatles %}
<div class="myradio">
{{ radio }}
</div>
{% endfor %}
</fieldset>
This code assumes you have a form myform with a field beatles that uses a RadioSelect as its widget.
As you can see, looping through the field beatles can allow you to add necessary classes (here class="myradio") for each radio button; hence, make your CSS styling possible and easier.
In your case, you might want to also loop through your gender field and then apply the appropriate classes.

django adminplus link disappears when grappelli is enabled

Recently, I added adminplus which automatically creates a link on the admin page to my custom view. E.g. admin.site.register_view('somepath', 'My Fancy Admin View!', view=my_view) should produce a 'Custom View' menu with a link named 'My Fancy Admin View!'. If I disable Grappelli, the menu & link appears, however when Grappelli is enabled, the menu & link disappears. My guess is Grappelli skips this menu because it is defined differently from the rest. Any advice would be greatly appreciated.
Thank to the hint provided by dan-klasson, I found a hack for my problem
Add the following code to Grappelli's admin/index.html
{% empty %}
<p>{% trans "You don´t have permission to edit anything." %}</p>
{% endfor %}
<!-- Code above is included as point of reference -->
<!-- Add the code below -->
<div class="grp-module" id="custom_views">
<h2>Custom Views</h2>
<div class="grp-row">
{% for path, name in custom_list %}
<strong>{{ name }}</strong>
{% endfor %}
</div>
</div>

Django. Cancel button for form in admin site

Is there any functionality in admin site that allow to implement for every add/change form cancel button, that redirects me to list of that form objects. I mean some general solution for any form.
Add admin/submit_line.html in your project's templates directory. Use the code from the default submit_line.html, and add your cancel button. You can link it to just "../" to make it always just go up one level. Then do any necessary CSS styling to make it look right.
Create a file: yourapp/templates/admin/submit_line.html
I use Bootstrap, but you can change this easily
{% extends "admin/submit_line.html" %}
{% block submit-row %}
{{ block.super }}
Cancel
{% endblock %}
Be sure that your application is above "admin" in INSTALLED_APPS.
Looks like this in German locale:
<input type="button" name="Cancel" value="Cancel">
You can this line anywhere inside admin/submit_line.html