Django 1.11: pass id to url to generate detail view - django

I've a list of "nanas" (babysitters) that I render correctly. Now I need that when someone clicks on one of them , a detail page (for only the clicked nana opens).
I think my problem is on my template for all the Nanas, in the href:
<a href="{% url 'app-administrador:nana' nana.id %}">
Or in the Urls.
All Nanas page:
This is listing nanas View:
class NanasView(View):
def get(self, request):
nanas = Nana.objects.all()
context = {'nanas': nanas}
return render(request, 'app_administrador/nanas-registradas.html', context)
It's URL:
url(r'^referencias_de_nanas', views.NanasReferenciasView.as_view(), name='referencias_de_nanas'),
All Nanas templates:
{% extends 'app_administrador/templates/base.html' %}
{% load staticfiles %}
{% block content %}
<!-- Member Entries -->
{% for nana in nanas %}
<!-- Single Member -->
<div class="member-entry">
<a href="extra-timeline.html" class="member-img">
<i class="entypo-forward"></i>
</a>
<div class="member-details">
<a href="{% url 'app-administrador:nana' nana.id %}">
<h4>
<p href="extra-timeline.html">{{ nana.nombre }} {{ nana.apellido_paterno }} {{ nana.apellido_materno }}</p>
{% if nana.foto %}
<img src="{{ nana.foto.url }}" class="img-rounded" width="160px"/>
{% endif %}
</h4>
<!-- Details with Icons -->
<div class="row info-list">
<div class="col-sm-4">
<i class="entypo-briefcase"></i>
<a href={{ nana.antecedentes_policiales }}>Antecedentes policiales</a>
</div>
<div class="col-sm-4">
<i class="entypo-twitter"></i>
#johnnie
</div>
<div class="col-sm-4">
<i class="entypo-facebook"></i>
fb.me/johnnie
</div>
<div class="clear"></div>
<div class="col-sm-4">
<i class="entypo-location"></i>
{{ nana.direccion }}
</div>
<div class="col-sm-4">
<i class="entypo-mail"></i>
{{ nana.correo }}
</div>
<div class="col-sm-4">
<i class="entypo-linkedin"></i>
johnkennedy
</div>
</div>
</a>
</div>
</div>
{% endfor %}
{% endblock %}
Nana's detail page:
My try on showing the detail page for clicked nana:
class NanasValidarReferenciasView(View):
def get(self, request, nana_id):
# nana_id_is = nana_id
nana = Nana.objects.get(id=nana_id)
context = {'nana': nana}
return render(request, 'app_administrador/validar-referencias-nana.html', context)
It's URL:
url(r'^nana', views.NanasValidarReferenciasView.as_view(), name='nana'),

You see your href looks like this: <a href="{% url 'app-administrador:nana' nana.id %}"> which is totally fine. This means that the url link adds the two string together into one address. I don't know exactly how your urls are set up so it could look something like this:
root_url/2
Where root_url is whatever you have and 2 is the nana.id. To pass that to the url-view, it needs to accept any integer variable. Something like this:
urls.py
url(r'^nana/(?P<nana_id>\d+)/$', views.nanas_specific, name='nana'),
The P stands for Parameter, and it uses Regex logic if you want to look that up.
Then in your views, you can have a function ready to accept the parameter:
views.py
def nanas_specific(request, nana_id):
Where nana_id contains the result from the urls parsing.

I mostly work with function based views, but I'm assuming the same logic applies to classbased views. The id is not part of the URL and hence is not passed on. Change the url to
url(r'^nana/(?P<nana_id>\d+)/$', views.NanasValidarReferenciasView.as_view(), name='nana'),

Related

Customize the style of a django.forms.BooleanField() containing a django.forms.CheckboxInput()

I included a contact-form on my webpage which looks like so:
I would like to style the "CC myself" - checkbox in the following ways:
The text "CC myself" is centered vertically within its box.
The checkbox should be right next to the text "CC myself".
The "forward"-symbol should be between text and checkbox, but directly next to the text and with more horizontal distance to the checkbox (on its right-hand side).
This is how I defined the contact form in forms.py:
from django import forms
class ContactForm(forms.Form):
# * Sender
from_email = forms.EmailField(
required=True,
label='Your Email',
widget=forms.TextInput(attrs={'placeholder': 'jsmith#example.com'}))
# * Optional CC to sender
cc_myself = forms.BooleanField(
required=False,
label='CC myself',
widget=forms.CheckboxInput(attrs={'class': 'fa fa-share'}))
# * Subject
subject = forms.CharField(required=True, label='Subject')
# * Message
message = forms.CharField(
widget=forms.Textarea(attrs={'placeholder': 'Dear Andreas ..'}),
required=True,
label='Message')
In the home.html template then, the form is displayed like so:
<form style="margin-left: auto;margin-right: 0;" method="post" action="{% url 'contact' %}">
{% csrf_token %}
<!-- * Neat autoformatting of the django-form via "pip install django-widget-tweaks"
Docs: https://simpleisbetterthancomplex.com/2015/12/04/package-of-the-week-django-widget-tweaks.html -->
{% for hidden in sendemail_form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in sendemail_form.visible_fields %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field|add_class:'form-control' }}
{% for error in field.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% endfor %}
<div style="text-align:center" class="form-actions">
<button type="submit" class="btn btn-success">
<!-- Search icons: https://fontawesome.com/icons?s=solid (syntax: class="fa fa-name-of-icon"))
Docs on how to implement: https://stackoverflow.com/questions/32612690/bootstrap-4-glyphicons-migration/41281304#41281304-->
<span class="fa fa-paper-plane"></span> Send Message
</button>
<!-- Add horizontal space: https://stackoverflow.com/questions/31198170/want-to-add-spacing-between-buttons/31199399#31199399 -->
<!-- Add cancel-button redirecting to "home" according to the following docs: https://simpleisbetterthancomplex.com/2015/12/04/package-of-the-week-django-widget-tweaks.html -->
<a href="{% url 'home' %}" class="btn btn-secondary">
<span class="fa fa-times"></span> Cancel
</a>
</div>
</form>
Edit on CSS-styling (bootstrap 4.x) employed in my project:
In my base.html wrapped around all my templates, the following is included:
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Docs for including fontawesome: https://stackoverflow.com/a/41281304/12298276 -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
Edit after trying out the first suggestion of #Danoram:
The result looks like this (only modification is the place of the "forward" - symbol inside the checkbox:
I would like to display the help_text='Decide if the message should be forwarded to you.' below the checkbox in grey, just like with the other fields. Also, the checkbox is still much bigger regarding its height compared to the label text "CC myself". And last but not least, the formatting of the entire contact-form column has gotten distorted. Especially the latter should be fixed, otherwise I can't implement it this way.
This was my best attempt (conserving the size of the checkbox).
Using an if check to render the cc field separately.
Although to do this I had to remove the classes from the checkboxinput and put them directly into the html
forms.py
cc_myself = forms.BooleanField(
required=False,
label='CC myself',
widget=forms.CheckboxInput())
home.html
<form style="margin-left: auto;margin-right: 0;" method="post" action="{% url 'contact' %}">
{% csrf_token %}
<!-- * Neat autoformatting of the django-form via "pip install django-widget-tweaks"
Docs: https://simpleisbetterthancomplex.com/2015/12/04/package-of-the-week-django-widget-tweaks.html -->
{% for hidden in sendemail_form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in sendemail_form.visible_fields %}
{% if field.label == 'CC myself'%}
<div class="row form-group">
<div class="col-3 col-lg-2 col-xl-auto">
<label>{{ field.label }} <label for="{{ field.id_for_label }}" class="fa fa-share"></label></label>
</div>
<div class="col-2">
{{ field|add_class:'form-control' }}
</div>
</div>
{% else %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field|add_class:'form-control' }}
{% for error in field.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% endif %}
{% endfor %}
<div style="text-align:center" class="form-actions">
<button type="submit" class="btn btn-success">
<!-- Search icons: https://fontawesome.com/icons?s=solid (syntax: class="fa fa-name-of-icon"))
Docs on how to implement: https://stackoverflow.com/questions/32612690/bootstrap-4-glyphicons-migration/41281304#41281304-->
<span class="fa fa-paper-plane"></span> Send Message
</button>
<!-- Add horizontal space: https://stackoverflow.com/questions/31198170/want-to-add-spacing-between-buttons/31199399#31199399 -->
<!-- Add cancel-button redirecting to "home" according to the following docs: https://simpleisbetterthancomplex.com/2015/12/04/package-of-the-week-django-widget-tweaks.html -->
<a href="{% url 'home' %}" class="btn btn-secondary">
<span class="fa fa-times"></span> Cancel
</a>
</div>
</form>

How to apply if else, if the keyword entered in search bar does not exists in Django

I have created a search button in my blogging application that returns the posts with the similar title.
views.py has
def search(request):
query = request.GET.get('query')
posts = Post.objects.filter(title__icontains=query).order_by('-date_posted')
params = {'posts' : posts}
return render(request, 'blog/search.html' , params)
base.html
<form method="get" class="form-inline my-2my-lg-0 " action="{% url 'search' %}">
<input class="form-control nav-item nav-link text-secondary" type="search" name="query" id="query" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success nav-item nav-link ml-1">Search</button>
</form>
and search.html
{% for post in posts %}
<!-- starting loop (posts is keyword from view) -->
<article class="media content-section">
<img class="rounded-circle article-img" src="{{post.author.profile.image.url}}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' post.author.username %}">{{ post.author }}</a>
<small class="text-muted">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<h2><a class="article-title" href="{% url 'post-detail' post.id%}">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content|slice:":200" }}</p>
{% if post.content|length > 200 %}
<div class="btn-group-sm">
<a class="btn btn-outline-secondary" href="{% url 'post-detail' post.id%}">Read More →</a>
</div>
{% endif %}
</div>
</article>
{% endfor %}
Now if the the user enters a keyword that is similar to the title of any post then those posts are returned. If no post title matches that keyword a black page is returned. Instead of a blank page I want a paragraph saying that "no post matches the title "
EDIT
How to get something like "no post matches the title {{query}} " instead of "no post matches the title " I get
Wrap your template like this:
{% if posts %}
{% for post in posts %}
...
{% endfor %}
{% else %}
<h2> No post matches the title. </h2>
{% endif %}
Since your posts queryset will be empty it will display the statement in the else block.

Using Instagram API to make users populate images into my Django application directly from Instagram Pictures

My use case or what I want to do is:
Users click a Upload button,
it authenticates user,
its shows Instagram images,
users select, and
user click upload button to upload images or videos (media) from
Instagram directly into my django app.
What I have done is:
Instagram integration:
pip install python-instagram
views.py:
#login_required()
def instagram_pictures(request, template='dashboard/add-instagram-pictures.html'):
user = request.user
gallery = []
gallery = Gallery.objects.filter(service_provider=user.service_provider_profile)
context = {'gallery': gallery}
return render(request, template, context)
#login_required()
def add_instagram_pictures(request, template='dashboard/add-instagram-pictures.html'):
access_token = "YOUR_ACCESS_TOKEN" # Dont know how this gets factored in for any user
client_secret = settings.SECRET_ID
api = InstagramAPI(access_token=access_token, client_secret=client_secret)
recent_media, next_ = api.user_recent_media(user_id="userid", count=10)
for media in recent_media:
print(media.caption.text)
template/my-gallery.html:
{% extends 'base.html' %}
{% load static %}
{% block title %}My Dashboard{% endblock %}
{% block content %}
<div class="page-header" style="background: url({% static 'img/banner1.jpg' %});">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="page-title">My Gallery</h1>
</div>
</div>
</div>
</div>
<div id="content">
<div class="container">
<div class="row">
{% include '_side_menu.html' %}
<div class="col-md-8 page-content">
<div class="inner-box text-center">
<a href="{% url 'dashboard:add-instagram-pictures' %}" class="btn btn-md btn-success">
<span class="fa fa-plus-circle"> Upload from Instagram</span>
</a>
<ul>
<!-- I will re-write this loop to redefine how images are rendered for the project. Maybe in Carousels-->
{% for p in photos %}
<li>{{ p.name }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
template/add-instagram-pictures.html:
{% extends 'base.html' %}
{% load static %}
{% block title %}Add Gallery{% endblock %}
{% block content %}
<div class="page-header" style="background: url({% static 'img/banner1.jpg' %});">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="page-title">Add Instagram Pictures</h1>
</div>
</div>
</div>
</div>
<div id="content">
<div class="container">
<div class="row">
{% include '_side_menu.html' %}
<div class="col-md-8 page-content">
<div class="inner-box text-center">
<a href="{% url 'dashboard:my-gallery' %}" class="btn btn-md btn-success">
<span class="fa fa-chevron-circle-left"> Back to Album List</span>
</a>
</div>
</div>
</div>
</div>
</div> {% endblock %}Add
url.py:
from django.conf.urls import url, include
from dashboard.views import dashboard, my_services, add_service, my_gallery, add_gallery, bank_profile, add_bank_profile, add_instagram_pictures
def ajax_photo_upload_view(args):
pass
urlpatterns = [
url(r'^$', dashboard, {}, name='home'),
url(r'^bank-profile/$', bank_profile, {}, name='bank-profile'),
url(r'^add-bank-profile/$', add_bank_profile, name='add-bank-profile'),
url(r'^my-services/$', my_services, name='my-services'),
url(r'^add-service/$', add_service, name='add-service'),
url(r'^add-gallery/$', add_gallery, name='add-gallery'),
url(r'^my-gallery/$', my_gallery, name='my-gallery'),
url(r'^add-gallery/$', add_instagram_pictures, name='add-instagram-pictures'),
]
settings.py:
# instagram settings
CLIENT_ID = "XXXXXXXXXXXXXXXXXXXX"
SECRET_ID = "XXXXXXXXXXXXXXXXXXXX"
How do I go about my use case as I have stated, my solution is in no way closer to what I want to do.

Use variable in statement in template

I want to use a variable in {% include %} statement in django templates. Specifically, I am trying to include a template in another template and i need to generate and pass url to be used in a button. How can I achieve this?
This is my troublesome part of form.html template:
<div class="col-md-12">
{% url 'accountant:gp_taxes:delete_rate' pk=field.value as delete_url %}
{% include 'includes/formset_inline.html' with delete_url=delete_url %}
</div>
and formset_inline.html:
<a class="btn btn-s btn-danger" href="{{ delete_url }}">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</a>
When I look at the url in my browser it is empty (I have <a class="btn btn-s btn-danger" href>).
How can I pass the url?
EDIT clarification for topic added.
I would suggest writing inclusion tag https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#inclusion-tags
#register.inclusion_tag('includes/formset_inline.html')
def formset_inline(delete_url):
return {'delete_url': delete_url}
And then
<div class="col-md-12">
{% url 'accountant:gp_taxes:delete_rate' pk=field.value as delete_url %}
{% formset_inline delete_url %}
</div>

Django 1.3 Pagination Not Showing Page Links and Showing all Records

I'm trying to set up Django Pagination in Django 1.3, It doesn't seem to be working, as I have over 5 records returned and the links are messed up
View:
def directory(request, bought_in_control_panel_id):
listings = Directory.objects.all().exclude(visible=False).order_by('rank', 'company__name').filter(company__uuid__in=local_uuids)
paginator = Paginator(listings, 5) # Show 25 contacts per page
# Make sure page request is an int. If not, deliver first page.
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
# If page request (9999) is out of range, deliver last page of results.
try:
page_listings = paginator.page(page)
except (EmptyPage, InvalidPage):
page_listings = paginator.page(paginator.num_pages)
return share.output_page(request, 'directory/directory.html', {'listings': page_listings, 'bought_in_control_panel_id': bought_in_control_panel_id})
Template:
{% block main %}
<link href="/media/css/bootstrap.min.css" rel="stylesheet">
<div class="container-fluid">
<div class="dbx-group">
<div class="dbx-box">
<h3 class="dbx-handle"><div class="tools"></div> <img src="/media/img/32x32/addressbook.png" style="position:absolute; margin-top:-16px;"><div class="title">Online Suppliers listings {% jms_help_link user 'directory_listings' %}</div></h3>
<h3 class="dbx-handle"><div class="tools"></div> <a title="Change region" href="{% url change_flag bought_in_control_panel_id iso %}"><img src="/media/img/flags-iso/48/{{ iso|lower }}.png" alt="Change region" align="right" style="margin-top:-45px;"></a><div class="title"></div></h3>
<ul class="dbx-content" width=98%>
{% if listings %}
{% for listing in listings %}
{% if listing.visible %}
<div class="well well-small" onclick="window.location.href = '{% url view_directory listing.uuid bought_in_control_panel_id %}'" style="cursor:pointer;">
<div class="row-fluid">
<div class="span12">
<a style="display:block" href="{% url view_directory listing.uuid bought_in_control_panel_id %}">
<h4>{{ listing.company.name }}</h4>
</a>
<div class="row-fluid">
<div class="span10">
<blockquote>{{listing.description|truncatewords:30}}</blockquote>
<p>Click for more info and downloads</p>
</div>
<div class="span2">
<img src="{% url view_banner listing.uuid %}" alt="">
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if listings.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ listings.number }} of {{ listings.paginator.num_pages }}.
</span>
{% if listings.has_next %}
next
{% endif %}
</span>
</div>
{% else %}
<p align="center"><b>No listings!</b></p>
{% endif %}
<div style="clear:both;"></div>
</div>
</div>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="/media/js/bootstrap.min.js"></script>
{% endblock %}
share.output_page:
def output_page(request, htmlpage, dct={}):
t = loader.get_template(htmlpage)
c = RequestContext(request,dct)
return http.HttpResponse(t.render(c))
In Django 1.3 you need to use:
{% for listing in listings.object_list %}
It's changed in Django 1.4.