NoReverseMatch Error, Django can't verify the edit page - class

$I have no solution for this error , please i need support, it gives noreversematch and it seems it cant reach my edit-page , the following if full details of the coding , thank you
$ Edit link to edit page:
{% if post.created_by == user %}
<div class="mt-3">
<a class="btn btn-success float-end"
href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}">Edit</a>
</div>
{% endif %}
$ views.py
#method_decorator(login_required, name='dispatch')
class PostUpdateView(UpdateView):
model = Post
fields = ['message']
template_name = 'edit_post.html'
pk_url_kwarg = 'post_id'
context_object_name = 'post'
def form_valid(self, form):
post = form.save(commit=False)
post.updated_by = self.request.user
post.updated_date = timezone.now()
post.save()
return redirect('topic_posts', board_id=post.topic.board.pk, topic_id=post.topic.pk)
$ urls.py
path('<int:board_id>/topics/<int:topic_id>/posts/<int:post_id/edit',
views.PostUpdateView.as_view(), name="edit_post"),
$html of the edit-page
<div class="container container-newtopic w-50">
<h1>Edit Post</h1>
<br>
{% include 'parts/alerts.html' %}
<div aria-label="breadcrumb">
<ol class="breadcrumb n1-head">
<li class="breadcrumb-item">Boards</li>
<li class="breadcrumb-item"><a href="{% url 'topics' post.topic.board.pk
%}">
{{post.topic.board.name}}</a></li>
<li class="breadcrumb-item active" aria-current="page"><a href="">Edit
Post</a></li>
</ol>
</div>
<form method="POST" action="" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{next}}">
{% include 'includes/form.html' %}
<button type="submit" name="btnaddtopicdj"
class="btn main-btn w-100 rounded-pill mt-5">Save Changes
</button>
</form>
</div>
$ error message:
NoReverseMatch at /boards/3/topics/20
Reverse for 'edit_post' with arguments '(3, 20, 23)' not found. 1 pattern(s) tried:
['boards/(?P<board_id>[0-9]+)/topics/(?P<topic_id>[0-9]+)/posts/<int:post_id/edit\\Z']
Reverse for 'edit_post' with arguments '(3, 20, 23)' not found. 1 pattern(s) tried:
['boards/(?P<board_id>[0-9]+)/topics/(?P<topic_id>[0-9]+)/posts/<int:post_id/edit\\Z']
href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}">Edit</a>

Related

Flask-paginate + MongoDB full text search Error $search had wrong type when hitting page 2

Having an issue with flask-paginate & pyMongo/MongoDB full text search. Pagination works well for me until the user tries to search for a 'post' in the database. It will display the first 6 (as I've set it in my case) results that there are but once you want to navigate to page 2 it throws an error reading:
pymongo.errors.OperationFailure: "$search" had the wrong type. Expected string, found null, full error: {'operationTime': Timestamp(1600978481, 2), 'ok': 0.0, 'errmsg': '"$search" had the wrong type. Expected string, found null', 'code': 14, 'codeName': 'TypeMismatch', '$clusterTime': {'clusterTime': Timestamp(1600978481, 2), 'signature': {'hash': b'\xd6b\xe7\x8eI\xa5\xea[\xb2\x0e5Y\xa2\xf3\x93R\xc6\xc1\xc4\x06', 'keyId': 6862628668309504003}}}
The same issue arises if I try and filter the search results using .sort("param", 1) - I've removed this 'feature' since but this is the same error I've encountered.
Werkzeug notes that the issue arises on line 63 in my search() route ie. pagination = Pagination(...).
My routes.py:
#app.route('/search', methods=("GET", "POST"))
def search():
page = request.args.get(get_page_parameter(), type=int, default=1)
per_page = 6
search_request = request.form.get("search")
all_posts = mongo.db.posts.find({"$text": {"$search": search_request}}).skip((page-1) * per_page).limit(per_page)
pagination = Pagination(
page=page, per_page=per_page,
total=all_posts.count(), record_name='all_posts')
return render_template('search.html', all_posts=all_posts, pagination=pagination, search_request=search_request)
My search.html template:
<div class="row">
{% for post in all_posts %}
<div class="col s12 l4">
<div class="card card-panel hoverable">
<div class="card-image center-align">
<img src="{{post.image_url}}" class="card-img">
</div>
<div class="card-content">
<h4 class="card-title">{{post.title}}</h4>
<p>{{post.description}}</p>
<p class="read-time">{{post.read_time}} minute(s), {{post.views}} views</p>
</div>
<div class="card-action">
Read
</div>
</div>
</div>
{% endfor %}
{% if all_posts.count() == 0 %}
<div class="center-align">
<h3>No posts found</h3>
</div>
{% endif %}
</div>
<!-- Pagination -->
<div class="row center-align">
{% if all_posts.count() > 1 %}
{{ pagination.info }}
{% endif %}
{{ pagination.links }}
Thanks for your help.

Remove file in form if constraint violation

I'm followed the tutorial to manage the upload of multiple files http://growingcookies.com/easy-multiple-file-upload-in-symfony-using-the-collectiontype-field/
The system for uploading multiple files works fine.
I added a constraint to allow only certain types of files and to set a maximum size.
When this constraint is enabled, the uploaded files are still present in the form but they are actually delete.
The javascript code always displays the files as present when in fact they are no longer present :
The buttons to delete the files are still present ..
Do you know how I can completely delete the form files in case of a constraint violation while displaying the error message ? Or do you have a better way to upload multiple files with constraints in Symfony 4 ?
My twig :
{% extends '#Ticketing/base.html.twig' %}
{% block title %}{{ 'New Ticket'|trans({}, 'TicketingBundle') }}{% endblock %}
{% block header %}<h1>{{ 'New Ticket'|trans({}, 'TicketingBundle') }}</h1>{% endblock %}
{% block form_group_class -%}
col-sm-8
{%- endblock form_group_class %}
{% block main %}
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
{% form_theme form 'bootstrap_4_layout.html.twig' _self %}
<div class="box box-danger">
<div class="box-header with-border">
<h3 class="box-title">{{ 'Create a new ticket'|trans({}, 'TicketingBundle') }}</h3>
</div>
{% form_theme form 'bootstrap_3_horizontal_layout.html.twig' _self %}
{{ form_start(form, {'attr': {'class': 'form-horizontal'} }) }}
<div class="box-body">
<div class="hr-line-dashed"></div>
<div id="filesProto" data-prototype="{{ form_widget(form.documents.vars.prototype)|e }}"></div>
<div class="form-group">
<label class="col-sm-2 control-label" for="ticket_form_documents">Pièce-jointe</label>
<div class="col-sm-8" id="filesBox">
{% set pos = 0 %}
{% for doc in form.documents %}
<div class="row">
<div class="col col-xs-1" id="jsRemove{{ pos }}" style="">
<button type="button" class="btn btn-danger" onclick="removeFile($(this));"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>
<div class="col col-xs-11" id="jsPreview{{ pos }}">{{ doc.vars.value.name }}</div>
<div style="display:none">
{{ form_widget(doc) }}
</div>
</div>
{% set pos = pos + 1 %}
{% endfor %}
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<div class="col-md-offset-2 col-sm-8">
<button id="dropbutton" class="btn bg-ticketing btn-flat form-control" type="submit">
{{ 'Submit the ticket'|trans({}, 'TicketingBundle') }}
</button>
</div>
</div>
<!-- /.box-footer -->
{{ form_end(form) }}
</div>
<script>
var fileCount = '{{ form.documents|length }}';
var removeButton = "<button type='button' class='btn btn-danger btn-xs' onclick='removeFile($(this));'><i class='fa fa-times' aria-hidden='true'></i></button>";
function removeFile(ob)
{
ob.parent().parent().remove();
}
function createAddFile(fileCount)
{
// grab the prototype template
var newWidget = $("#filesProto").attr('data-prototype');
// replace the "__name__" used in the id and name of the prototype
newWidget = newWidget.replace(/__name__/g, fileCount);
newWidget = "<div style='display:none'>" + newWidget + "</div>";
hideStuff = "";
hideStuff += "<div class='col col-xs-1' id='jsRemove" + fileCount + "' style='display: none;'>";
hideStuff += removeButton;
hideStuff += "</div>";
hideStuff += "<div class='col col-xs-11' id='jsPreview" + fileCount + "'>";
hideStuff += "</div>";
hideStuff += "<div class='col-sm-8'>";
hideStuff += "<button type='button' id='jsBtnUpload" + fileCount + "' class='btn btn-default'>";
hideStuff += "<i class='fa fa-plus'></i> {{ 'Pièce-jointe' | trans }}";
hideStuff += "</button>";
hideStuff += "</div>";
$("#filesBox").append("<div class='form-group'>" + hideStuff + newWidget + "</div>");
// On click => Simulate file behaviour
$("#jsBtnUpload" + fileCount).on('click', function(e){
$('#ticket_form_documents_' + fileCount + '_file').trigger('click');
});
// Once the file is added
$('#ticket_form_documents_' + fileCount + '_file').on('change', function() {
// Show its name
fileName = $(this).prop('files')[0].name;
$("#jsPreview" + fileCount).append(fileName);
// Hide the add file button
$("#jsBtnUpload" + fileCount).hide();
// Show the remove file button
$("#jsRemove" + fileCount).show();
// Create another instance of add file button and company
createAddFile(parseInt(fileCount)+1);
});
}
$(document).ready(function(){
createAddFile(fileCount);
fileCount++;
});
</script>
{% endblock %}
The code is available here: https://github.com/oanalivia/Multiple-File-Upload-in-Symfony-using-the-CollectionType-Field
one banale solution would be to adapt the output and just filter the docs out, that don't have a value.
{% for doc in form.documents %}
{% if doc.vars.value %} {### <-- new 1/2 ###}
<div class="row">
<div class="col col-xs-1" id="jsRemove{{ pos }}" style="">
<button type="button" class="btn btn-danger" onclick="removeFile($(this));"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>
<div class="col col-xs-11" id="jsPreview{{ pos }}">{{ doc.vars.value.name }}</div>
<div style="display:none">
{{ form_widget(doc) }}
</div>
</div>
{% set pos = pos + 1 %}
{% endif %} {### <-- new 2/2 ###}
{% endfor %}
if you're using a fairly new version of twig (>= 2.10, I believe), you can also only modify the first line of that section:
{% for doc in form.documents|filter(doc => doc.vars.value) %}

Two For loops in one HTML page using Jinja (Not working)

I am trying to use one loop in my HTML File using Jinja template
First loop is for showing data on slider
Second is for list tag
The problem is that both are not showing data simultaneously
I have to remove one loop to make other loop working
For Slider
<ul class="rslides" id="slider">
{% for post in slider %}
<li>
<img src="{{post.Image}}" alt="">
<div class="caption">
{{post.Heading}}
</div>
</li>
{% endfor %}
for List Tag
{% for post in posts %}
<div class="article">
<div class="article-left">
<img src="{{post.Image}}" alt="" />
</div>
<div class="article-right">
<div class="article-title">
<p style="color:black">{{ post.Date }}<a class="span_link" href="#"><!-- <span class="glyphicon glyphicon-comment"></span>0 </a><a class="span_link" href="#"><span class="glyphicon glyphicon-eye-open"></span></a><a class="span_link" href="#"><span class="glyphicon glyphicon-thumbs-up"></span>89</a> --></p>
<a class="title" href="{{url_for('post',post_id=post._id)}}">{{ post.Heading }}</a>
</div>
<div class="article-text">
<p>{{ post.NewsType }}...</p>
<!-- <img src="{{ url_for('static', filename='images/more.png')}}" alt="" /> -->
<div class="clearfix"></div>
</div>
</div>
<div class="clearfix"></div>
</div>
{% endfor %}
Flask Code
allpost = posts.find( {"NewsType": {"$in": it}}).sort('Date',pymongo.DESCENDING).skip((page - 1) * per_page).limit(per_page)
pagination = Pagination(page=page,per_page=5,total=allpost.count(), search=search, record_name='allpost')
return render_template('index.html', posts=allpost,pagination=pagination,slider=allpost)
Both loops are getting values from mongodb collection .
Is there anyway to solve this problem?
A MongoDB query hands back an object that fetches results lazily. And once those results are fetched, that's it.
Your code is trying to consume allposts twice. What you're seeing is that the first loops through works, leaving nothing for the second loop.
One way to fix that is to consume the results once, turning them in to a list, before passing the list to your template. That is, add
allpost = list(allpost)
before passing that to the template.

How to put a html tag (span) inside a button in twig file symfony 2.8?

I have been trying to customize a form individual field, following the symfony documentation:
http://symfony.com/doc/master/form/form_customization.html#how-to-customize-an-individual-field
But I have not had success in my attempt.
This is my twig:
{% block _Formulario_personalizado_widget %}
<span class="icon-icon-buscar-libros fs1"></span>
{% endblock %}
{{ form_widget(Formulario.Buscar, {'id':"BuscarPorCriterio", 'attr':{'class':'btn btn-primary active'}}) }}
This is my form in the cotroller:
->add('Buscar',ButtonType::class, array('block_name'=> 'personalizado'))
And this controller returns a twig with next form name:
array("Formulario"=>$form->createView())
However, the output is like this:
<span class="icon-icon-buscar-libros fs1"></span>
<button type="button" id="BuscarPorCriterio" name="form[Buscar]" class="btn btn-primary active">Buscar</button>
And I actually need this output (with SPAN INSIDE Button):
<button type="button" id="BuscarPorCriterio" name="form[Buscar]" class="btn btn-primary active"><span class="icon-icon-buscar-libros fs1"></span> Buscar</button>
Thank you in advance for your help!
Usually, the submit buttons are not created inside the controller, nor the Type, but you can create them in the twig template directly. Like:
{% form_start(Formulario) %}
{% form_row(Formulario.field) %}
{# more fields here #}
<button type="button">
<span class="icon-icon-buscar-libros fs1"></span>
Buscar
</button>
{% form_end(Formulario) %}

Symfony3 - My handwritten post form don't work

I'm trying to learn how to work with Symfony3.
I'm trying to make a simple form to connect. The form is succefully redirecting me to my page /login so that is super. But it don't sent to the page the post informations :/ Do you know how to do ?
This is my controller's code :
public function showAction(Request $request){
$motDePasse = $request->request->get("motDePasse", "");
$identifiant = $request->request->get("identifiant", "");
if($motDePasse != "" && $identifiant != ""){
// I make my user object and put it in $_SESSION
}
return $this->render("login/show.html.twig", [
"identifiant" => $identifiant
]);
}
And there is my twig code :
{% extends "::base.html.twig" %}
{% block body %}
<div id='loginBox'>
<div class='center'>
<div class='logo'></div>
<h1>HyperPlanning</h1>
<form action="{{ path('login') }}" method='post'>
<input name='identifiant' type='text' placeholder='Identifiant' value="{{ identifiant }}"><br/>
<input name='motDePasse' type='password' placeholder='Mot de passe'><br/>
<input name='remember' type='hidden' value='0'><br>
<input name='remember' type='checkbox' value='1' checked> <span>Rester connecter</span><br>
<input type='submit' value='Se connecter'>
</form>
</div>
</div>
{% endblock %}
I don't have a configured Symfony3 project on my laptop but Symfony v2.7. However, I assume the script is going to work in Symfony3 as well.
I have a DefaultController with the actions login and manageLogin. The first action contains the above html form and the second makes a dump of $request. Both actions have as route name the respective actionName. In the html form I am using as action="..." the route name of the manageLoginAction.
When submitting the form the manageLoginAction is rendered.
DefaultController:
<?php
// [...]
class DefaultController extends Controller
{
// [...]
/**
* #Route("/konto/login", name="login")
* #Template()
*/
public function loginAction(Request $request)
{
return array(
'base_dir' => realpath($this->container->getParameter('kernel.root_dir').'/..'),
);
}
/**
* #Route("/konto/manageLogin", name="manageLogin")
* #Template()
*/
public function manageLoginAction(Request $request)
{
dump($request);
die;
}
// [...]
}
login.twig.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}
<div id='loginBox'>
<div class='center'>
<div class='logo'></div>
<h1>HyperPlanning</h1>
<form action="{{ path('manageLogin') }}" method='post'>
<input name='identifiant' type='text' placeholder='Identifiant' value="Identifier"><br/>
<input name='motDePasse' type='password' placeholder='Mot de passe'><br/>
<input name='remember' type='hidden' value='0'><br>
<input name='remember' type='checkbox' value='1' checked> <span>Rester connecter</span><br>
<input type='submit' value='Se connecter'>
</form>
</div>
</div>
{% endblock %}
{% block javascripts %}{% endblock %}
</body>
dump($request):