How can I use Django inline formset with Bootstrap-select plugin? - django

I've been trying to use the Django inline formset with the bootstrap-select plugin from here https://developer.snapappointments.com/bootstrap-select/ and every other thing works perfectly, I'm able to successfully call the plugin on another two selects that I have in my form and I'm using the inline formset to add new authors on my book. When i put the "selectpicker" class, it only works once, when the page is loaded, but when I press the button to add more authors, the select field is not loaded.
So I have a question... can I use the two together? If yes, how? If not, is there any workaround to be able to search in a selection field?
Bellow is a image to how my form looks when i press the big green "Add" button at the end of the form.
You can see that there is only two fields, one less than the first one.
If any code is needed, please let me know and i will add right away.
Thanks!
EDIT:
Here are my codes, as asked by Chris:
My template:
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block content %}
{% load static %}
<form method="POST" class="form" action="">
{% csrf_token %}
[other fields]
...
<!-- HERE I HAVE MY TWO OTHER SELECT FIELDS WHICH WORK PERFECTLY -->
<div class="container">
<div class="col-sm-12">
<div class="form-group">
<div class="row">
<div class="col-sm-6">
<label>Editora do Livro:</label>
{{ form.editora_cod_editora|add_class:"selectpicker form-control"|attr:"data-live-search='true'" }}
</div>
<div class="col-sm-6">
<label>Categoria do Livro:</label>
{{form.categoria_cod_categoria|add_class:"selectpicker form-control"|attr:"data-live-search='true'" }}
</div>
</div>
</div>
</div>
</div>
<!-- HERE START MY ONLINE FORM, AS SHOWS THE PRINT -->
<div class="container">
<div class="col-sm-12">
<hr>
<h4>Adicionar Autor</h4>
<hr>
<div class="form-group bg-light rounded ">
{{ autor_livro.management_form }}
{% for form in autor_livro.forms %}
<div class="{% cycle 'row1' 'row2' %} formset_row m-5 inline-form">
{{ form.autor_cod_autor|add_class:"selectpicker form-control"|attr:"data-live-search='true'" }}
{{ form.ordinal_autorlivro|add_class:"form-control" }}
{{ form.autor_funcao|add_class:"form-control" }}
</div>
{% endfor %}
</div>
</div>
<div class="container">
<div class="col-sm-12">
<div class="form-group">
<div class="row">
<div class="col-sm-8"></div>
<div class="col-sm-4">
<button type="submit" class="btn-outline-primary btn float-right">Salvar</button>
</div>
</div>
</div>
</div>
</div>
</form>
{% block scripts %}
<!-- HERE I HAVE MY SCRIPT THAT MAKES THE INLINE FORM WORK WITH THAT PLUGIN -->
<script src="{% static 'js/jquery.formset.js' %}"></script>
<script type="text/javascript">
$('.formset_row').formset({
addText: 'Adicionar Autor',
deleteText: 'Remover',
prefix: 'autorlivro_set'
});
</script>
{% endblock %}
{% endblock %}

The answer is the behaviour of the bootstrap-select plugin. You are activating it by using the class "selectpicker". After loading the page some javascript magic takes the elements with the class selectpicker and creates the widget you see. The "select" you now see is not your original <select> but an auxillary widget, your <select> is still there but hidden from your view.
Now when you add another form the javascript magic is not called again, so that you get a new form where your <select> is hidden somewhere from the user's eyes.
In order to get it rendered nicely again you need to run the required javascript after you have added a new form. django-dynamic-formset provides an option called added allowing you define a function which is called after the new form has been added. Form more details see the formset options here.
So define the function and call it after adding a form. In your case your script could look like this:
<script type="text/javascript">
var activate_select = function(row){
row.find('.selectpicker').selectpicker();
};
$('.formset_row').formset({
addText: 'Adicionar Autor',
deleteText: 'Remover',
prefix: 'autorlivro_set,
added: activate_select
});
</script>

Related

How can I remove the navbar in these three parts in my python project?

I am currently trying to build a website with python django. At the moment I am making a dashboard for the website. On the dashboard I want to show three tiles for different menu options. Dashboard
Ignore the content this is just a placeholder for now. As you can see in every part of the dashboard the navbar is included. My code for the dashboard looks like following:
{% extends 'base.html' %}
{% block titel %}Dashboard{% endblock %}
{% block content%}
<div class="container-fluid">
<h1 class="fw-bold">Dashboard</h1>
<div class="row">
<div class="col-sm-4">
<div class="card">
<div class="card-body" >
{% include 'todolist/index.html' %}
</div>
</div>
</div>
<div class="col-sm-4">
<div class="card">
<div class="card-body">
{% include 'todolist/index.html' %}
</div>
</div>
</div>
<div class="col-sm-4">
<div class="card">
<div class="card-body">
{% include 'todolist/index.html' %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
The base for all the sites are in a extra file called base.html. In this file is also the navbar defined.
How can I prevent that the navbar will be in every part of the dashboard while still using the extends part?
You can put the navbar section in another template rather than having it in the base template. This way you can decide when to use it separetely than the base template.

Django Calculation inside HTML

I wanted to do something simmilar to this suing django. but somehow i it doesn't work. how do i fix it?
for statik in statistik{
print(statik*total/100)
}
Is there any documentation regarding what I'm trying to implement to my django app? Thank you
Here's the HTML :
{% if statistics %}
{% for statik in statistics|slice:":4" %}
<div class="mb-3">
<div class="small text-gray-500">{{ statik.name }}
<div class="small float-right"><b>{{ statik.voters }} of {{ total }} Voters</b></div>
</div>
<div class="progress" style="height: 12px;">
<div class="progress-bar bg-success" role="progressbar" style="width: {{ statik.voters * total/100 }}%" aria-valuenow="50"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
{% endfor %}
{% else %} <p>END TABLE</p>
{% endif %}
It is recommended you do calculations of any sort in view and pass it in context.
If you still want to go this route there are no math template tags except add included so you should create custom template tags or use django-mathfilters

How can I pass an image ID from the view into my routes.py, when the images are displayed in the view via a for loop?

I'm building a simple portfolio website where the owner will be able to manage a gallery page, Adding, Editing and Removing posts. I am printing the images from the DB using a for loop and need a way in order to get either the name of the image or the ID of the image and send the value back to the route in order to delete the row from the DB. Any suggestion would be much appreciated.
Additional information:
Using Flask w/ SQLalchemy & WTforms
Sample of how I'm displaying the images and accompanying data:
{% for image in Posts | reverse %}
<div class="row pt-3">
<div class="col">
<img class="img-fluid rounded" src="static/gallery_images/{{image.image }}" alt="">
</div>
</div>
<div class="row pt-4">
<div class="col">
<h3 style="display: inline">{{image.title}}</h3>
<p class="font-italic text-muted" style="display: inline">
{% if image.sold_flag %}
- Sold
{% else %}
- Available
{% endif %}
</p>
<p class="text-muted">{{image.date_posted.strftime('%d/%m/%Y')}}</p>
</div>
</div>
<div class="row">
<div class="col">
<p class="font-weight-normal">{{ image.description }}</p>
</div>
</div>
<div class="row">
{% if current_user.is_authenticated %}
<div class="col text-left">
<button type="button" class="btn btn-dark">Edit</button>
<button type="button" class="btn btn-danger">Delete</button>
</div>
{% endif %}
</div>
<hr class="border">
{% endfor %}
There are multiple ways to store the id and use it for a route call. Using purely what you have shared, you can add a call to the button to the respective endpoints:
Assuming you have a method images.delete(id) to delete images and that you want to keep with the button tag on your code:
<a href={{url_for('delete.edit', id=image.id)}}>
<button type="button" class="btn btn-dark">
Delete
</button>
</a>
However, I would really recommend for you to use a form to submit the delete, as opposed to a GET request generated above. This way you can have it secured with WTForm CSRF token.
Example:
HTML
<form action="{{url_for('delete.edit', id=image.id)}}" method="POST" role="form">
{{ form.hidden_tag() }}
</form>
Python
## Make sure to create the delete form
class DeleteImage(Form):
pass

How to bring data from DB of a User into form to update it

I'm studying django and trying to make a simple CRUD, following the djangoGirls tutorial. But unfortunatelly they don't show how to UPDATE data.
I'm already Inserting, Reading/listing how may I Delete and Update?
I listed the users with a link to edit it:
{% extends 'bloodDonation/master.html' %}
{% block content %}
<h1 class="center">LIST DONATORS<h1>
<ul>
{% for donator in donators %}
<div class="row">
<div class="container">
<div class="col s12 blue-grey lighten-5 border_lighten">
<div class="col s12 m12 padding_normal">
{{ donator.name }}
<div id="icon" class="right">
<i class="material-icons">edit</i>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</ul>
{% endblock %}
As you can see, I have an a tag pointing to edit_donator url.
How may I pass the ID/data of the selected/clicked user so I can pull his data and throw it inside the form?
Form creation:
class EditDonatorForm(forms.ModelForm):
class Meta:
model = Donator
fields = [ 'name', 'age', 'email', 'phone', 'bloodType', 'observation' ]
Trying to pass the ID:
url(r'^donator/(?P<pk>\d+)/update/$', views.edit_donator, name='edit_donator'),
How may I get data from database and already place it inside form so I can perform an Update?
You don't require to send the data to another link. You can update the details on the same URL.
Change your HTML to this:
{% extends 'bloodDonation/master.html' %}
{% block content %}
<h1 class="center">LIST DONATORS<h1>
<ul>
{% for donator in donators %}
<div class="row">
<div class="container">
<div class="col s12 blue-grey lighten-5 border_lighten">
<div class="col s12 m12 padding_normal">
{{ donator.name }}
<div id="icon" class="right">
<i class="material-icons">edit</i>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</ul>
{% endblock %}
In your view write,
if 'edit-donator' in request.GET:
edit_data = YourModel.objects.get(id=request.GET['edit-donator'])
form = EditDonatorForm(instance=edit_data)
This will get the data from the model and pass it to the template.
Now you can perform the update.
Hope this helps :)

Django: include html saved as string in template rendering

I build an HTML table in my views.py function and I want to include it in a template that I already have when rendering. I see that the div is created, but the HTML table is not created. What is the problem?
this is the line in views.py:
render(request, 'aztracker/import_data.html', {'my_html':html_data})
where html_data is like
"<table><tr><th>column1</th></tr><tr><td>data1</td></tr> ....</table>"
and I have this section in my import_data.html:
<div class="bootstrap-iso">
<div class="tbl_container_numbers">
{{ my_html }}
</div>
</div>
this is the sanme div after rendering:
<div class="bootstrap-iso">
<div class="tbl_container_numbers">
</div>
</div>
I found the problem. To render an html code stored as a string we should use the built-in autoescape tag:
<div class="bootstrap-iso>
<div class="tbl_container_numbers">
{% autoescape off %}
{{ my_html }}
{% endautoescape %}
</div>
</div>