I am trying to build a form that allows users to provide a review of an area they have visited However, every iteration of trying to link the review to the beach model proves to be wasted effort.
Could someone please tell me why I can't get the form to show. I am consistently getting an error:
Reverse for 'beaches-review' with arguments '('',)' not found. 1 pattern(s) tried: ['review/(?P<beach_id>[0-9]+)/$']
or some variation of that.
My code is below. Thank you for any help you can provide.
Models.py
class Beach(models.Model):
name = models.CharField(max_length=80)
location = models.CharField(max_length=200)
video = models.FileField(upload_to='beachvideo', blank=True)
beachPic = models.ImageField(default='default.jpg', upload_to='beachphotos', blank=True)
datetimeInfo = models.DateTimeField(auto_now=True)
lat = models.FloatField()
lon = models.FloatField()
info = models.TextField()
def average_rating(self):
all_ratings = map(lambda x: x.rating, self.review_set.all())
return np.mean(all_ratings)
def __str__(self):
return f'{self.name}'
class Review(models.Model):
RATING = (
('1', 'Avoid'),
('2', 'Not Great'),
('3', 'Decent'),
('4', 'Awesome'),
('5', 'The Best'),
)
beach = models.ForeignKey(Beach, on_delete= models.CASCADE)
author = models.ForeignKey(User, null=True, blank=True, on_delete= models.CASCADE)
ratingRank = models.CharField(max_length= 100, blank=False, choices=RATING)
waveIntensityRank = models.CharField(max_length= 100, blank=True, choices=RATING)
crowdednessRank = models.CharField(max_length= 100, blank=True, choices=RATING)
pollutionRank = models.CharField(max_length= 100, blank=True, choices=RATING)
noiseLevelRank = models.CharField(max_length= 100, blank=True, choices=RATING)
servicesRank = models.CharField(max_length= 100, blank=True, choices=RATING)
comments = models.TextField(max_length=250, blank=True)
pub_date = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return reverse('beaches-home')
def __str__(self):
return self.author.username
Forms.py
class ReviewForm(forms.ModelForm):
class Meta():
model = Review
fields = ('ratingRank', 'author', 'waveIntensityRank', 'crowdednessRank', 'pollutionRank', 'noiseLevelRank', 'servicesRank', 'comments')
Urls.py
urlpatterns = [
path('', views.beachView, name='beaches-home'),
path('beach/<int:pk>', views.beachDescription, name='beaches-description'),
path('search/', views.searchResultsView.as_view(), name='search-results'),
path('review/<int:beach_id>/', views.addReview, name='beaches-review'),
]
Views.py
def beachView(request):
beachView = {
'beachView': Beach.objects.all()
}
return render(request, 'beaches/index.html', context = beachView)
def beachDescription(request, pk):
beachDesc = {
'beachDesc': Beach.objects.get(pk=pk)
}
return render(request, 'beaches/description.html', context = {'beachDesc': beachDesc} )
def review_list(request):
latest_reviews = Review.objects.order_by('-pub_date')[:9]
def addReview(request, beach_id):
beachRev = get_object_or_404(Beach, pk=beach_id)
if request.method == 'POST':
review_form = ReviewForm(data=request.POST)
if review_form.is_valid():
rating = review_form.cleaned_data['rating']
comment = review_form.cleaned_data['comments']
user_name = review_form.cleaned_data['author']
wave_intensity = review_form.cleaned_data['waveIntensityRank']
crowds = review_form.cleaned_data['crowdednessRank']
pollution = review_form.cleaned_data['pollutionRank']
noise_level = review_form.cleaned_data['noiseLevelRank']
services = review_form.cleaned_data['servicesRank']
review = Review()
review.beach = beachRev
review.author = user_name
review.rating = rating
review.waveIntensityRank = wave_intensity
review.crowdednessRank = crowds
review.pollutionRank = pollution
review.noiseLevelRank = noise_level
review.servicesRank = services
review.comments = comment
review.pub_date = datetime.datetime.now()
review.save()
return HttpResponseRedirect(reverse("beaches-description", args=(beach_id,)))
#if request.method == "POST":
#review_form = review_form(data=request.POST)
#if review_form.is_valid():
# rating = review_form.cleaned_data
# post.date = timezone.now()
# post.save()
# return redirect('beaches/beachReview.html')
#else:
# form=ReviewForm()
return render(request, 'beaches/beachReview.html', context= {'review_form': review_form, 'beachRev': beachRev,})
class searchResultsView(ListView):
model = Beach
template_name = 'beaches/searchResults.html'
def get_queryset(self): # new
query = self.request.GET.get('q')
object_list = Beach.objects.filter(
Q(name__icontains=query) | Q(location__icontains=query)
)
return object_list
HTML
{% extends 'base.html' %}
{% load static %}
{% block content %}
<head>
<link rel="stylesheet" href="{% static 'css/bestbeach.css' %}">
</head>
<h1> {{ beachDesc.name }} </h1>
<h4> Location: {{ beachDesc.location }} </h4>
<h4> Rating: {{ beachDesc.ratingRank }} </h4>
<table>
<tr>
<td> <img src="{{ beachDesc.beachPic.url }}" width="350px" height="200px"/> </td>
</tr>
<tr>
<td> <video width="350px" height="200px" loop="loop" preload="auto" controls>
<source src="{{ beachDesc.video.url }}" type="video/mp4">
Your browser does not support the video.
</video>
</td>
</tr>
</table>
<h4> Information: {{ beachDesc.info }} </h4>
<a href="{% url 'beaches-review' beach_id %}">
<button class="goButton" type="submit">Leave a Review</button>
</a>
{% if review_list %}
<div>
{% for r in review_list %}
<div>
<h4> Reviews: </h4>
<p> {{ r.author }} </p>
<h6> rated {{ r.rating }} of 5 </h6>
<p>{{ r.comments }}</p>
</div>
{% endfor %}
</div>
{% else %}
<p>No reviews are available.</p>
{% endif %}
{% endblock %}
Just to sanitize #ha-neul's comment.
You expose a Beach object using the beachDescription view, providing the template variable beachDesc.
beachDesc now hold all the attributes of the object's model.
So to get the id you can do:
<a href="{% url 'beaches-review' beachDesc.id %}">
OR
<a href="{% url 'beaches-review' beachDesc.pk %}">
Alternatively
you could add the following method to your Beach model
def get_absolute_beach_review_url(self):
return reverse('beaches-review', kwargs={'beach_id':self.id})
and link beachDesc.get_absolute_beach_review_url in your template.
Related
I'm working on a TicTacToe game using Django/Djangotemplates, Python and a bit Javascript. I've come across a problem tho. i only have one Button which is for-looped 9 times. its ID is its index. Now I'm not certain how to add the {{index}} which i defined in the for loop in the javascript onclick function.
here the html template
<div class="grid-container">
{% for index in object.board %}
<div class="grid-item">
<input onclick="change(button.id)" class="buttonsize btn-outline-purple" type="submit" value="" name="button" id="{{index}}">
</div>
{% endfor %}
</div>
</div>
</article>
</form>
<script>
function change(inputid){
console.log("test")
var elem = document.getElementById(inputid);
if (elem.value=="") elem.value = "X"
}
</script>
here the models.py
class TicTacToe(models.Model):
player1 = models.ForeignKey(User, on_delete=models.CASCADE, default="X", related_name="tictactoe_as_player1")
player2 = models.ForeignKey(User, on_delete=models.CASCADE, default="O", related_name="tictactoe_as_player2")
current_player = models.ForeignKey(User, on_delete=models.CASCADE, related_name="tictactoe_current_player")
title = models.CharField(max_length=100)
board = models.CharField(max_length=9, default="012345678")
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('tictactoe-detail', kwargs={'pk': self.pk})
and here the views.py
class TicTacToeCreateView(LoginRequiredMixin, CreateView):
model = TicTacToe
template_name = 'website/newgame_form.html'
fields = ['player1', 'player2', 'current_player', 'title', 'board']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class TicTacToeDetailView(UpdateView):
model = TicTacToe
fields = ['player1', 'player2', 'current_player', 'title', 'board']
def clean(self):
if 'button0' in self.data:
print('button0')
i also got a database but there is really not much in there except the player IDs
Adding index to the onclick should be OK
<input onclick="change({{index}})" class="buttonsize btn-outline-purple" type="submit" value="" name="button" id="{{index}}">
I am stuck on a problem I am having trying to implement a 'Like' button into my django application.
I have the functionality working for the models, and even in the html template the code works if I manually add a like from a user.
It seems like my Ajax may be the issue, but I can't seem to figure out why.
Here is my models.py:
class Post(models.Model):
direct_url = models.URLField(unique=True)
post_url = models.URLField()
post_title = models.CharField(max_length=300)
time_posted = models.DateTimeField(default=timezone.now)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Like(models.Model):
liker = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='likes')
date_created = models.DateTimeField(default=timezone.now)
def save(self, *args, **kwargs):
super(Like, self).save(*args, **kwargs)
And here is my views.py
class PostListView(LoginRequiredMixin, generic.ListView):
model = Post
template_name = 'homepage/home.html'
ordering = ['-time_posted']
context_object_name = 'posts'
paginate_by = 6
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['now'] = datetime.now()
context['likesbyuser'] = Like.objects.filter(liker=self.request.user)
return context
def likePost(request):
if request.method == 'GET':
post_id = request.GET['post_id']
likedpost = Post.objects.get(pk=post_id) # getting the liked post
if Like.objects.filter(post=likedpost, liker=request.user).exists():
Like.objects.filter(post=likedpost, liker=request.user).delete()
else:
m = Like(post=likedpost, liker=request.user) # creating like object
m.save() # saves into database
return HttpResponse(likedpost.likes.count())
else:
return HttpResponse("Request method is not a GET")
This is part of the template, where I am putting the buttons to use the Ajax which should call the like function:
{% for i in post.likes.all %}
{% if user == i.liker %}
<a class='likebutton' data-catid="{{ post.id }}"><i id='like{{ post.id }}' class="btn fas fa-heart fa-lg post-buttons "></i></a>
{% elif forloop.last %}
<a class='likebutton' data-catid="{{ post.id }}"><i id='like{{ post.id }}' class="btn far fa-heart fa-lg post-buttons "></i></a>
{% endif %}
{% empty %}
<a class='likebutton' data-catid="{{ post.id }}"><i id='like{{ post.id }}' class="btn far fa-heart fa-lg post-buttons "></i></a>
{% endfor %}
{% endfor %}
And here is the Ajax code I am adding to the base.html in script tags.
<script type="text/javascript">
$('main').on('click', '.likebutton', function(){
var catid;
catid = $(this).attr("data-catid");
$.ajax(
{
type:"GET",
url: "/likepost/",
data:{
post_id: catid
},
success: function(data){
if(data==0){
$('.like' + catid).toggle();
$('#like' + catid).toggleClass("far fas");
$('#likecount' + catid).html('');
console.log(data+'if');
}
else if(data==1){
if($('.like' + catid).is(":hidden"))
{
$('.like' + catid).toggle();
}
$('#like' + catid).toggleClass("far fas");
$('#likecount' + catid).html(data + ' like');
console.log(data+'elseif');
}
else{
$('#like' + catid).toggleClass("far fas");
$('#likecount' + catid).html(data + ' likes');
console.log(data+'else');
}
}
})
});
</script>
I have tried adding event.preventDefault(); to the ajax call, but that did not fix my issue.
I found the issue.
I was pointing the Ajax code at "main" as seen in the following snippet:
...
<script type="text/javascript">
$('main').on('click', '.likebutton', function(){
...
My issue was that I forgot to surround the block with the main tag when I ported this project over.
In my base.html I added the following code:
<main role="main" class="container h-100">
{% block content %}
{% endblock content %}
</main>
This fixed the issue.
Hi everyone the comments are not working with CBV my form not even saving the comment. here is my code i will love if anyone help me with this.my models.py is
class Product(models.Model):
title = models.CharField(max_length=110)
slug = models.SlugField(blank=True, unique=True)
price = models.DecimalField(decimal_places=2, max_digits=6)
discount_price=models.FloatField(blank=True, null=True)
size = models.CharField(choices=SIZE_CHOICES, max_length=20)
color = models.CharField(max_length=20, blank=True, null=True)
image = models.ImageField(upload_to=upload_image_path)
description = models.CharField(max_length=1000)
featured = models.BooleanField(default=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
time_stamp = models.DateTimeField(auto_now_add=True)
objects=ProductManager()
def get_absolute_url(self):#i use this in product_list.html to go to detail page
#return "/product/{slug}".format(slug=self.slug)
return reverse("products:detail", kwargs={"slug" : self.slug})
def __str__(self):
return str(self.title)
#property
def name(self): #sometime in html i say name istead of title so to make it work i wrote this
return self.title
def product_pre_save_reciever(sender, instance, *args, **kwargs):#i inherit unique slug generator from utils to here so when i create aa new instance it slug automatically generate. and i i create two t shirts it give a random straing to tshirt 2nd slug
if not instance.slug:
instance.slug=unique_slug_generator(instance)
pre_save.connect(product_pre_save_reciever, sender=Product)
class Comment(models.Model):
product=models.ForeignKey(Product , related_name="comments", on_delete=models.CASCADE)
name = models.CharField(max_length=255)
body=models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s'%(self.product.title, self.name)
my forms.py is:
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['name', 'body']
widgets ={
'name':forms.TextInput(attrs={'class':'form-control'}),
'body':forms.Textarea(attrs={'class':'form-control'}),
}
the views.py is:
class CommentCreateView(CreateView):
model = Comment
form_class = CommentForm
template_name = 'add-comment.html'
# fields = '__all__'
def form_valid(self, form):
form.instance.product_id = self.kwargs['pk']
return super().form_valid(form)
success_url = reverse_lazy('list')
my add-comment.html is:
{% extends "base.html"%}
{% load crispy_forms_tags%}
{% block content %}
<h2 class="text-center">comment here...</h2>
<div class="col-md-6 offset-md-3">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
{{form|crispy}}
</fieldset>
<!-- <div class="form-group"><button class="btn btn-outline-info" type="submit">Pubmit</button>-->
<!-- </div>-->
<!-- <input type="submit" value="Submit" class="btn btn-secondary">-->
<button class="btn btn-secondary">Add comment</button>
</form>
</div>
{% endblock %}
and my urls.py is:
urlpatterns = [
# path('featured/' , ProductFeaturedListView.as_view()),
#path('featured/<int:pk>' , ProductFeaturedDetailView.as_view()),
path('' , ProductListView.as_view(), name= "list"),
path('new/' , ProductCreateView.as_view() , name="product-create"),
path('<slug:slug>/update/' , ProductUpdateView.as_view() , name="product-update"),
path('<slug:slug>/delete/' , ProductDeleteView.as_view() , name="product-delete"),
#path('product-fbv/' , product_list_view),
#path('product/<int:pk>' , ProductDetailView.as_view()),
path('<slug:slug>/comment' , CommentCreateView.as_view() , name="add-comment"),
path('<slug:slug>' , ProductDetailSlugView.as_view() , name="detail"),
# path('product-fbv/<int:pk>' , product_detail_view),
]
and the error comes when I hit post comment is:
The problem comes from the fact you don't provide any pk keyword argument to your view.
From the urls.py, I can see you have a slug kwargs though. You can then identify the matching product with its slug.
In your views.py, replace:
form.instance.product_id = self.kwargs['pk']
by
form.instance.product = Product.objects.get(slug=self.kwargs['slug'])
Explanation:
Here you want to associate your comment with the matching product. So, for that, you use NameOfModel.objects.get(query), which returns one single instance of your model (here Product), matching the query. In your case the only way to retrieve the object is getting the keyword argument slug from your url and search it on your Product slug field, so here the query is slug=self.kwargs['slug'].
I am working on a school project where I have to program a REST API application that interacts with a database with basic POST and DELETE operation:
Here is my Python Flask file:
from flask import Flask, render_template, redirect, url_for, jsonify, request, Response, abort
from flask_bootstrap import Bootstrap
import dbinteraction
app = Flask(__name__)
Bootstrap(app)
#app.route('/')
def hello_world():
return redirect(url_for('index'))
#app.route('/index')
def index():
return render_template('index.html')
#app.route('/allrecipes')
def allrecipes():
return render_template('allrecipes.html')
#app.route('/ingredients')
def ingredients():
return render_template('ingredients.html')
#app.route('/api/v1.0/recipes', methods=['GET'])
def get_recipes():
# init
recipes = []
# get the task list from the db
recipes_list = dbinteraction.getRecipes()
# prepare the task list for jsonify
for item in recipes_list:
recipe = prepare_for_json(item)
recipes.append(recipe)
# return the task data
return jsonify({'recipes': recipes})
#app.route('/api/v1.0/ingredients', methods=['GET'])
def get_ingredients():
# init
ingredients = []
# get the user_ingredients list from the db
ingredients_list = dbinteraction.getIngredients()
# prepare the user_ingredients list for jsonify
for item in ingredients_list:
ingredient = prepare_for_json_ingredient(item)
ingredients.append(ingredient)
# return the ingredients data
return jsonify({'ingredients': ingredients})
#app.route('/api/v1.0/ingredients', methods=['POST'])
def insert_ingredient():
# get the request body
add_request = request.json
# check whether an ingredient is present or not
if (add_request is not None) and ('name' in add_request) and ('quantity' in add_request):
text = add_request['name']
quantity = add_request['quantity']
# insert in the database
dbinteraction.insertIngredients(text, quantity)
return Response(status=201)
# return an error in case of problems
abort(403)
#app.route('/api/v1.0/ingredients/<string:ing_name>', methods=['DELETE'])
def delete_ingredient(ing_name):
# delete the ingredient
ingredient = dbinteraction.removeIngredient(str(ing_name))
return Response(status=200)
def prepare_for_json(item):
"""
Convert the recipe in a dictionary for easing the JSON creation
"""
recipe = dict()
recipe['name'] = item[0]
recipe['link'] = item[1]
recipe['difficulty'] = item[2]
return recipe
def prepare_for_json_ingredient(item):
"""
Convert the ingredient in a dictionary for easing the JSON creation
"""
ingredient = dict()
ingredient['name'] = item[0]
ingredient['quantity'] = item[1]
return ingredient
if __name__ == '__main__':
app.run(debug=True)
I also programmed and tested the dbinteraction functions for the database and they work fine. My problem is in the ingredients.html part. I load and see the page as I want, a modifiable list of ingredients with the delete button. But when I click on the delete I get a Uncaught ReferenceError: (name of the ingredient) is not defined at HTMLAnchorElement.onclick
This are my html and javascript files:
{% extends "bootstrap/base.html" %}
{% block title %}All recipes page{% endblock %}
{% block styles %}
{{super()}}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.12/css/all.css"
integrity="sha384-G0fIWCsCzJIMAVNQPfjH08cyYaUtMwjJwqiRKxxE/rx96Uroj1BtIQ6MLJuheaO9" crossorigin="anonymous">
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ url_for('static', filename='kima2js.js') }}"></script>
{% endblock %}
{% block content %}
<div class="container" style="text-align: center">
<h1><i class="fas fa-utensils" style=""></i><br>
Insert an ingredient:
</h1>
<div id="ingredients_list" class="form-inline"></div>
<div id="insertingredient">
<form id="addForm"class="form-inline" method="POST">
<div class="form-group">
<label for="ingredientName">Ingredient:</label>
<input type="text" id="ingredientName" class="form-control" name="name"/>
</div>
<div class="form-group">
<label for="ingredientQuantity">Quantity:</label>
<input type="text" id="ingredientQuantity" class="form-control" name="quantity"/>
</div>
<button type="submit" class="btn-sm">Add</button>
</form>
</div>
</div>
{% endblock %}
... the javascript:
function addIngredient() {
$("#ingredients_list ul").empty();
$("#ingredientName").val('');
$("#ingredientQuantity").val('');
getIngredients();
}
function getIngredients() {
$.getJSON("http://127.0.0.1:5000/api/v1.0/ingredients", function(data){
var ingredients = data["ingredients"];
var len = ingredients.length;
for(var i = 0 ; i<len ; i++) {
var t = ingredients[i];
$("#ingredients_list ul").append("<li class='list-group-item list-group-item-text'>"+t.name+" "+t.quantity
+" <a class='delete btn btn-default' onclick='deleteIngredient("+ t.name +")'>" +
" <span class='glyphicon glyphicon glyphicon-remove'></span>Delete</a></li>");
}
});
}
function deleteIngredient(ing_name) {
$.ajax("/api/v1.0/ingredients/"+ing_name,
{
method: 'DELETE',
success: function (status) {
// update the list of printed ingredients: called when the DELETE is complete
getIngredients();
}
}
);
}
$(document).ready(function () {
$("#ingredients_list").append("<ul></ul>");
$("#ingredients_list ul").empty();
getIngredients();
$("#addForm").submit( function(){
var name = $("#ingredientName").val();
var quantity = $("#ingredientQuantity").val();
var ingredient = {'name': name, 'quantity': quantity};
var json = JSON.stringify(ingredient);
$.post({
"url": "http://127.0.0.1:5000/api/v1.0/ingredients",
"data": json,
"contentType":"application/json",
"success": addIngredient
});
return false;
});
});
I can't see what I am doing wrong. My only guesses are on the onclick part. Because I have tested singularly all the other pieces of code in previous labs
You just need to make sure that the value of ing_name is in quotes when you write it as a parameter to onclick, as follows:
$("#ingredients_list ul").append("<li class='list-group-item list-group-item-text'>"+t.name+" "+t.quantity
+" <a class='delete btn btn-default' onclick='deleteIngredient(\""+ t.name +"\")'>" +
" <span class='glyphicon glyphicon glyphicon-remove'></span>Delete</a></li>");
Otherwise javascript thinks ing_name is a variable name (and the variable is not defined).
The .html file is
<tbody>
{% for row in results %}
<tr class="{% cycle 'row1' 'row2' %} clickable-row" data-href="{% url "perception:detail" pk=row.object.pk %}">
{% for item in row.cols %}
{{ item }}
{% endfor %}
{% if row_actions_template %}
<td class="row-actions">{% include row_actions_template with object=row.object %}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
The .js file is
$(function(e){
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
});
The views.py file is
class PerceptionIndexView(StaffRestrictedMixin, FrontendListView):
page_title = _('Perception')
model = Perception
template_name = 'loanwolf/perception/index.html'
pjax_template_name = 'loanwolf/perception/index.pjax.html'
# row_actions_template_name = 'loanwolf/perception/list-actions.inc.html'
url_namespace = 'perception'
def active(self, obj):
if obj.is_active:
return icon(obj.get_icon(), css_class='green-text', tooltip=_('Active'))
else:
return icon(obj.get_icon(), css_class='red-text', tooltip=_('Inactive'))
def notes_count(self, obj):
return obj.notes.count()
notes_count_label = _('Notes')
def get_change_url(self, obj):
return obj.get_absolute_url()
class Meta:
ordering = ('-created', '-modified')
sortable = ('start_date', 'end_date', 'created', 'state', 'modified')
list_filter = ('state', 'is_active', customer, error)
list_display = (
'__unicode__', 'context_menu', 'state', 'start_date', 'end_date', 'current_balance',
'operation_error', 'modified', 'created', 'notes_count', 'active'
)
The part of the models.py file is
#python_2_unicode_compatible
class Perception(xwf_models.WorkflowEnabled, TimeStampedModel):
loan = models.ForeignKey('loans.Loan')
state = xwf_models.StateField(PerceptionWorkflow)
start_date = models.DateField(_('Start date'))
end_date = models.DateField(_('End date'), blank=True, null=True)
current_balance = models.DecimalField(_('Current balance'),
default=0, decimal_places=2, max_digits=11)
operation_error = models.SmallIntegerField(_('Operation error'), default=0)
notes = GenericRelation(Note)
def get_absolute_url(self):
return reverse('perception:detail', kwargs={'pk': self.pk})
def get_icon(self):
if self.is_active:
return 'check_circle'
else:
return 'remove_circle'
def save(self, *args, **kwargs):
rs = super(Perception, self).save(*args, **kwargs)
return rs
#Property
def __str__(self):
return six.text_type(_('Perception #%07d') % self.pk)
#property
def firstname(self):
first_name = self.loan.request.customer.user.first_name
return first_name
#property
def lastname(self):
last_name = self.loan.request.customer.user.last_name
return last_name
#property
def context_menu(self):
tpl = 'perception/context-menu.inc.html'
return mark_safe(render_to_string(tpl, {
'user': self.loan.request.customer.user,
'customer': self.loan.request.customer,
}))
The perception/context-menu.inc.html file looks like
{% load i18n %}
<div class="customer-context-menu closed {% if customer.gender == 0 %}male{% else %}female{% endif %}">
<b class="unselectable">
{{ customer.icon }}
{{ user.get_full_name }}
</b>
<ul>
<li class="tip"></li>
<li>{% trans "Profile" %}</li>
<li>{% trans "Alerts" %}</li>
<li>{% trans "Messaging" %}</li>
<li>{% trans "Requests" %}</li>
<li>{% trans "Documents" %}</li>
<li>{% trans "Logs" %}</li>
<li class="separator"></li>
{% if customer.phone_1 %}
<li class="phone">{{ customer.phone_1 }}</li>
{% endif %}
<li><i class="material-icons">email</i> {{ user.email }}</li>
<li><i class="material-icons">printer</i> {% trans "Print" %}</li>
</ul>
</div>
In the row image, I could click on the button associated to Randy Senger which open a little window with different options on the same page similar to enter image description here. Actually, there is a clickable-row associated to this row. The problematic is located when I clicked on the button. When I click on the button it opened the little window for approximately two seconds, and it render on another page a little as if I was clicking on the row. I think I could use a preventDefault on my .js file so that when I click on the button, it is not affected by clickable-row. Could anyone have an idea how I could modify my .js file to fix this?
P.S. Please let me know if the question is unclear.
What should be the issue here?
$(function(e){
$(".clickable-row").on('click', function() {
window.location = $(this).data("href");
});
});
$(".customer-context-menu").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
});
Unfortunately, I know nothing of Python. But it seems though, that your problem is about firing events for wrapping elements on your DOM. This is related to event bubbling.
Should you bind an event to a parent and a child, clicking on the child will fire both events, unless you specify the context where your event is supposed to execute.
event.stopPropagation should stop the event handling from being notified to the parent.
$('.child').on('click', function(){
e.stopPropagation();
console.log('only the child fires the event');
});
In any case, have you tried to retrieve the event.target of your jQuery event? It should be different according to where you click inside the parent.
<script>
$('.clickable-row').on('click', function(event){
// Every event returns an event object when specified as a callback parameter
console.log(event.target);
if ($(event.target).is('.my-class')){
// Do code for specific clicked element
}
});
</script>
I really hope this helps!