I am completely new to django and I am currently working on this program which is already in production.
Now I need to save certain forms to a sqlite database and I've watched some tutorials however I cannot understand how to do this.
Here is a portion of the code:
{% block content %}
<!-- Modal -->
<div class="card shadow-sm">
<div class="card-header" id="headingOne">
<h5 class="mb-0"> Receptas</h5>
<span class="d-flex flex-row-reverse"><button class="btn btn-secondary" id="save_recipe_btn" type="button"><i class="bi bi-save"></i></br> Saugoti</button></span>
</div>
<div id="card-base" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<div class="row">
<div class="col">
{% csrf_token %}
{{recipe_form.ibu}}
{{recipe_form.abv}}
<div class="row">
<div class="col">{{recipe_form.name|as_crispy_field}}</div>
<div class="col">{{recipe_form.style|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col">{{recipe_form.batch_size|as_crispy_field}}</div>
<div class="col">{{recipe_form.boile_time|as_crispy_field}}</div>
<div class="col">{{recipe_form.efficiency|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col">{{recipe_form.primary_age|as_crispy_field}}</div>
<div class="col">{{recipe_form.secondary_age|as_crispy_field}}</div>
<div class="col">{{recipe_form.age|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col">{{recipe_form.pub_date|as_crispy_field}}</div>
</div>
<div class="row">
<div class="col">{{recipe_form.notes|as_crispy_field}}</div>
</div>
</div>
Now I need to save forms like name, style, batch size and so on. In all the tutorials I watch they do something like doing method = post and making the button type = submit
However, this whole code looks quite a bit different than what they do in the tutorials and I am unsure whether I still should be saving in the same way or should I do something different here.
Could you please help me get on the right track?
Thank you very much!
Related
I am working on an application that has a page with a table that is a list of users. Each user has a button which pops up a modal that does something. I am trying to create the modal that will get the user information when the button in clicked, additionally, I need in that modal some logic based on the user information and some more data. I am thinking that it makes sense to create a separate view for it but since each view must be on a different url, the concept of the modal does not makes sense (for me), because I want it to be on the same url.
Is it possible to have a modal with a different view that will have a separate logic? Since the modal is included in the template and it is basically just one template, then, can one template have 2 views?
What is the best way to implement the modal using django? And how to pass data to it, I need the data from the row that was selected + some more data from db. I have the data from the context but manipulating that using JQuery for me is a bad idea - because I am using a python session on the backend that communicates with another api, so when user clickes the modal save button, a python request needs to be done, this means I need a view for it.
Here is my try
Modal
{% block modal %}
{% load static %}
{% load authorization_tags %}
<!-- Modal -->
<div class="modal fade" id="{{modal_id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="row">
<div class="col-lg-5">
<img class="d-block w-100"
src="{% static 'app/assets/images/security-shield1.png' %}"
alt="First slide">
Use access control to deauthorize user
</div>
<div class="col-lg-7">
<h2 class="h2-responsive product-name">
<strong>{{user.real_name}}</strong>
</h2>
<h4 class="h4-responsive">
<span class="green-text">
{{user.username}}
</span>
</span>
</h4>
<div class="accordion md-accordion" id="accordion1" role="tablist" aria-multiselectable="true">
<div class="card">
<div class="card-header" role="tab" id="heading2">
<a data-toggle="collapse" data-parent="#accordion1" href="#collapse1" aria-expanded="true"
aria-controls="collapse1">
<h5 class="mb-0">
Current Authorizations <i class="fas fa-angle-down rotate-icon"></i>
</h5>
</a>
</div>
<div id="collapse1" class="collapse show" role="tabpanel" aria-labelledby="heading1"
data-parent="#accordion1">
<div class="card-body">
{% for right in people_rights|user_active_rights:user.id %}
{{right.room}}
{% endfor %}
</div>
</div>
</div>
</div>
<div class="accordion md-accordion" id="accordion2" role="tablist" aria-multiselectable="true">
<div class="card">
<div class="card-header" role="tab" id="heading2">
<a data-toggle="collapse" data-parent="#accordion2" href="#collapse2" aria-expanded="true"
aria-controls="collapse2">
<h5 class="mb-0">
Available Authorizations <i class="fas fa-angle-down rotate-icon"></i>
</h5>
</a>
</div>
<div id="collapse2" class="collapse show" role="tabpanel" aria-labelledby="heading2"
data-parent="#accordion2">
<div class="card-body">
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="text-center">
<button type="button" class="btn btn-lg" data-dismiss="modal"><span>Close</span></button>
<button class="btn btn-lg"><span>Authorize</span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock modal %}
a piece of table and the modal included in the same template
{% include 'app/admin/users/user_authorize.html' with modal_id="authModal" user=row areas=areas rooms=rooms people_rights=people_rights %}
{%if row.empno %}
<td class="txt-oflo">{{ row.empno }}</td>
{% else %}
<td class="txt-oflo">-</td>
{% endif %}
<td>
{% with "#"|add:row.id as buttonId %}
<button id={{buttonId}} class="btn btn-lg" data-toggle="modal" data-target="#authModal">
<span>Authorize</span>
</button>
{% endwith %}
</td>
</tr>
You can try the following steps to solve the issue.
Create a separate view for the modal on a separate url.
Take the modal data out of this html file and place it in another html file. The empty modal in the original html should look something like this.
<div id="SampleTable" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">sample title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="sample_datatable">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
Render that new html from the new view that was created. The ajax request that will be activated from the button that gives us the modal table might look something like this.
#app.route('/sample_data', methods=['GET', 'POST'])
def modal_table():
try:
data = request.args.get('arg')
database_data = Table.query.filter(Table.data == data).all()
result_dict = [u.__dict__ for u in database_data]
except Exception as e:
traceback.print_exc()
return render_template('modal_table.html', data=enumerate(result_dict))
The button in the original html that results in the modal table should be configured in a way using ajax requests that it renders data from the new html into the old modal data like this.
function get_sample_data() {
$.ajax({
url:"/sample_data", //the page containing python script
type: "GET", //request type,
data: {},
async:true,
beforeSend: function(){
$('#sample_datatable').html('Loading..');
},
success:function(result){
$('#sample_datatable').html(result);
}
});
}
You can call this javascript function from the button that is supposed to show the modal table.
I have a very small form in a bootstrap modal including just two fields: a TextAreaField and a Submit button. My TextAreField is DataRequired.
On top of that this field uses CKEditor (similar to quillsJS) to make the text area WYSIWYG.
Problem is that the form submits even when no data has been entered, and reloads the parent page.
I would very much like to know how to prevent that form submission and raise the validation error when no data has been entered.
I would like to get WTForm validation and not the browser's (which anyway doesn't work either for this case).
I should also mention, in case it matters, that my modal is a partial file (jinja).
My trigger for the modal is this, living in perfume-cursor.html
Edit
And this is my modal (in a partial file perfume-modals.html)
<div class="modal fade" id="reviewPerfumeModal" tabindex="-1" role="dialog" aria-labelledby="reviewPerfumeModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteUserModal">Please Leave a Review</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method=POST action="{{ url_for('reviews.review_perfume', perfume_id=perfume._id) }}" id="form-review">
<fieldset class="form-group">
<div class="form-group">
{{ form.review(class="form-control form-control-md", placeholder="Review", id="description") }}
</div>
</fieldset>
<div class="modal-footer">
<div class="form-group">
{{ form.submit(class="btn btn-primary") }}
</div>
</div>
</form>
</div>
</div>
</div>
</div>
The id="description" is what CKEditor uses to render that text area field as a WYSIWYG editor, btw.
I would really appreciate a lot any help on this!!
Thanks in advance!
Update:
In case it helps this is my form class, although I'm pretty sure the issue is modal related and not WTF related:
class AddReviewForm(FlaskForm):
review = TextAreaField("Review", validators=[DataRequired()])
submit = SubmitField("Post Review")
This is ultimately just one box. But since it has the 'for' loop, it should have 3 boxes horizontally aligned.
<div class="album py-5 bg-light">
<div class="container">
{% for hobby in hobbies.all %}
<div class="row">
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img class="card-img-top" src="{{ hobby.image.url }}"/>
<div class="card-body">
<p class="card-text">{{ hobby.summary }}</p>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
I keep having this:
What will I do?
Here you go with a solution
<div class="album py-5 bg-light">
<div class="container">
<div class="row">
{% for hobby in hobbies.all %}
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img class="card-img-top" src="{{ hobby.image.url }}" />
<div class="card-body">
<p class="card-text">{{ hobby.summary }}</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
You class="row" should be outside the loop.
class="row" creates row in a table format that means each item within a loop will create a row and then a column inside i.e. you see your each cards in new row.
For getting the cards horizontally, all the cards should be place within a single row.
I have a list of banking transactions that I'm listing. I'm currently using bootstrap for my HTML/CSS. I found some template code that works well enough for what I want to do, but I've run into a problem: there's no way to know the id of the collapsing div element for the parent element. It's easier to see the html than to explain:
{% for key, value in transactions.items %}
<div id="accordion">
<div class="card">
<div class="card-header" id="heading-1">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#whatid" aria-expanded="true" aria-controls="whatid">
{{ key }}
</a>
</h5>
</div>
{% for key2, value2 in value.items %}
<div id="whatid" class="collapse show" data-parent="#accordion" aria-labelledby="heading-1">
<div class="card-body">
<div id="accordion-1">
<div class="card">
<div class="card-header" id="heading-1-1">
<h5 class="mb-0">
<a class="collapsed" role="button" data-toggle="collapse" href="#collapse-1-1" aria-expanded="false" aria-controls="collapse-1-1">
{{ key2 }}
</a>
</h5>
</div>
{% for tr in value2 %}
<div id="collapse-1-1">{{ tr.description }}</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
The attributes href, id and most importantly aria-controls of the child div element can't be known ahead of time and therefore won't be correctly associated with the button click. Is it possible to do this? It's a bit of a chicken before the egg problem, so I don't really know what there is to do.
I have a series of 6 modals that are created through a flask/jinja2 frame work loop and 1 modal that is an example outside of the loop. The modals all populate and populate correctly when looking at the page source. The example modal that is outside the loop shows without issue, however the other 6 modals will not fire.
https://www.sfiltrowani.pl/filter_instructions is the live site with the problem.
https://github.com/rscales02/sfiltrowani is the full code git repository.
This is for a flask app run on AWS elastic beanstalk. I was able to get the example modal to show by defining modal id and data target manually, those were the only changes I made from a copy/paste of the original modal code and original link to modals.
example link identical links from A-F
{{ _('(instrukcja photo F)') }}
modal loop to create image modals for instructions
{% for image in images %}
<!-- Modal -->
<div class="modal fade" id="{{ image }}" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<img id='modal-img' src="{{ url_for('static', filename='images/instructions/' + image) }}" alt="{{ loop.index }}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% endfor %}
Expected results a modal that fires for each photo in my instructions. Current results only example modal will show.
[Edit]
I am new to the stack, edited to show the 3 lines of code that were hidden, due to lack of indentation. Thanks and sorry!
Your link does not point to the modal to show .
The modal needs an ID that is referenced by data-target
{{ _('(instrukcja photo F)') }}
<div class="modal-dialog" id="this-modal-id">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<img id='modal-img' src="{{ url_for('static', filename='images/instructions/' + image) }}" alt="{{ loop.index }}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
I fixed it! It would appear that modal id's are sensitive to specific formatting and not just random strings. Previous version that did not work had id and data-targets of 'instrukcja*.jpg' when '.jpg' was removed, the modals function perfectly.