Fairly new to Django and Python, I am trying to build a detail view and a list view for a bunch of pictures I have uploaded. My list view works and shows all the pictures I have but I cannot figure out how to create a detailview that would let me look at only one picture.
In my "mysite" directory I have a url.py containing
urlpatterns = patterns('',
url(r'^photo/', include('photo.urls', namespace = "photo")),
)
Then in my "photo" directory I have
from photo import views
urlpatterns = patterns('',
url(r'$', views.ListImage.as_view(),name ='Photo-List',),
url(r'^/image/(?P<pk>\d+)/$', views.ImageView.as_view(),name='image-view',),
)
I have uploaded a bunch of pictures and I can see them when I visit my local website 800local../photo. But if I want to see one picture only, the address ../photo/image/1 returns a 404.
My Folder can be found at https://github.com/henrigeek/Django
List view will return object_list and Detail view return object.
{% if object %}
{{object.title}}
................
{% else %}
{% for img_obj in object_list %}
{{ img_obj.title }}
................
{% empty %}
No images found
{% endfor %}
{% endif %}
You can refer here Class based view
Related
I want to show a data with different feature .. So, there are 2 role where admin have 5 columns on the table. when the teacher only have 4 columns on the table. I change the HTML already but when I return classlist.html on teacherpage views.py .. it return the admin classlist.html that have 5 columns on the table.
Here is my code :
Urls.py (Teacher APP):
from django.urls import path
from teacherpage import views
urlpatterns = [
path('', views.index, name='index'),
path('classlist/', views.classlist, name='classlist'),
]
Views.py (Teacher APP):
def classlist(request):
data = classModel.objects.all()
classlist= {
"classlist" : data
}
return render(request,'classlist.html', classlist)
It is complicated without the actual codes of the project from you, but here is an idea about how you can use the same view and same html file for two different tables. For example, if your user's role is stored in the User model, then you can use this code in classlist.html:
{% if user.is_authenticated %}
{% if user.role == 'admin' %}
<table with five columns>
{% else %}
<table with four columns>
{% endif %}
{% else %}
no table for you
{% endif %}
FYI, you do not need to modify any views or urls to make it work.
Not sure how to pass additional context data into various allauth forms which includes my own templates. For my own views I'm using get_context_data() which is working fine. I'm including small templates into a master template such as a header, footer, side bar etc. Everything is working except when allauth kicks in such as login, logout, email confirmation window etc my context variables are not passed so images in my left side bar are not showing up but allauth works fine.
I've tried a few things but I believe the ideal option is to inherit from allauth views for that function such as login, password reset, confirm email etc, supply my own context variable data.
In my accounts.views.py, I'm expecting this to fail as the template doesn't exist but the form still shows up and the UserProfile image isn't being shown in the left side bar.
from allauth.account.views import ConfirmEmailView
class EmailViewExt(ConfirmEmailView):
template_name = "account/signup_alternate1.html"
def get_context_data(self, **kwargs):
context = super(ConfirmEmailView).get_context_data(**kwargs)
context['userprofile'] = UserProfile.objects.get(user=self.request.user)
return context
In my template left_bar_base.html which is included from my overridden allauth template.
{% if userprofile.avatar_picture %}
<img src="{{ userprofile.avatar_picture.url }}" class="card-img-top" alt="...">
{% else %}
<img src="{% static 'placeholder.png' %}" class="card-img-top" alt="...">
{% endif %}
In my email_confirmation.html I have this at the top.
{% extends "ui/base.html" %}
{% load i18n %}
{% load account %}
{% block header %}
{% include "ui/loggedin_header.html" %}
{% endblock %}
{% block left %}
<div class="row no-gutters justify-content-start">
{% include 'ui/left_bar_base.html' %}
{% endblock %}
{% block content %}
... allauth template code...
Came across the solution.
My EmailViewExt(ConfirmEmailView) was never being called.
So instead of using allauths.urls I put this right above the allauths.urls.
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/email/', EmailViewCustom.as_view(), name="email"),
path('accounts/', include('allauth.urls')),
Now the context variable I've added is being passed into my templates. So I guess I have to add all of the urls from allauth for the ones I want to replace.
Want to know how to identify and output the view function that renders a template in HTML.
Need it for debugging purposes.
Something like this:
{% if request.view == "index" %}
<title>Company Name</title>
{% else %}
<title>{{ other_page_title }} ยป Company Name</title>
{% endif %}
You could use:
{% if request.resolver_match.url_name == "index" %}
Comparing against the name given to the url in your urls.py, for example:
urlpatterns = [
path("home/", views.index, name="index"),
]
If you're using class-based views, you could add a name attribute to your view class, and then access it in your template.
class MyView(TemplateView):
name = 'my_view'
You can access that in your template with {{ view.name }}.
I'm working on a Django site that displays a list of projects. You go to a page, you see a project, you click it, and you can then see project details and have the option to edit the page.
For each individual project, I use a template called project.html. Then on that page, I have a link to edit_project.html
Edit Project
Whenever I try to load the project page to view, I get this error:
Reverse for 'edit_project' with arguments '('',)' not found. 1
pattern(s) tried: ['edit_project/(?P\d+)/$']
I checked the urls, and they seemed fine. So, I tried hard-coding a project id that I knew was in the database. For example, I called:
Edit Project
instead of calling that same thing with "project.id". When I did that, the error went away.
Why does this work with a hard-coded value instead of a project.id variable?
I also tried deleting the database and all the migrations in case something strange was happening there. I got the same issue though.
Here is the code I used to set everything up in case it is helpful.
project.html
{% extends "profile/base.html" %}
{% block content %}
<p>
Edit Project
</p>
<p>Status: {{ status }}</p>
{% endblock content %}
edit_project.html
{% block content %}
<p>{{ project }}</p>
<p>Edit project:</p>
<form action="{% url 'profile:edit_project' project.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Save Changes</button>
</form>
{% endblock content %}
views.py
#login_required
def edit_project(request, project_id):
"""Edit an existing project"""
project = Project.objects.get(id=project_id)
#Make sure the project belongs to the owner
if project.owner != request.user:
return Http404
if request.method != 'POST':
#Initial request; pre-fill form with the current entry
form = ProjectForm(instance=project)
else:
#POST data submitted; process data
form = ProjectForm(instance=project, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('profile:project',args=[project.id]))
context = {'project':project, 'form':form}
return render(render, 'profile/edit_project.html', context)
(project) forms.py
class DateInput(forms.DateTimeInput):
input_type = 'date'
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['name','description','status', 'project_type', 'start_date','end_date', 'due_date']
labels = {'name':'Name', 'description':'Description:', 'status':'Status', 'project_type':'Project Type',
'start_date':'Start Date', 'end_date':'End Date', 'due_date': 'Due Date',}
widgets ={'description':forms.Textarea(attrs={'cols':80}),'start_date':DateInput(),
'end_date':DateInput(),'due_date':DateInput()}
urls.py
urlpatterns = [
#Home page
url('^$', views.index, name='index'),
#Show all projects
url('projects/$', views.projects, name='projects'),
#Details for single project
url('^projects/(?P<project_id>\d+)/$', views.project, name='project'),
#Page for editing a single project
url('^edit_project/(?P<project_id>\d+)/$', views.edit_project, name='edit_project'),
]
I have a index.html where my form is implemented:
...
{% block searchform%} {% endblock %}
...
In my search/ folder I have two files.
search.html, which is the actual form for the index.html
{% extends 'index.html' %}
{% block searchform %}
<form method="get" action="/results/">
<table>
{{ form.as_table }}
<tr>
<td> </td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table>
{% endblock %}
and the file result.html, where I want to see my search results:
{% if query %}
<h3>Results</h3>
...
{% endif %}
urls.py:
from django.conf.urls import include, patterns, url
from dev_devices.views import *
urlpatterns = patterns('',
url(r'^$', include('haystack.urls')),
url(r'^results/$', results, name = 'results')
)
view.py
def results(request):
return render_to_response('results.html')
My problem is, that there are no results showing up. When I click on the submit Button of my form, I will redirected to the correct file (results.html), but no results are showing up. This question exists already but i found no answer, so can someone help me? Thank you !
Well, you aren't passing any results to the template. Check out your views.py:
def results(request):
return render_to_response('results.html')
Your template has this logic:
{% if query %}
<h3>Results</h3>
...
{% endif %}
query is not a variable in context. You'd have to pass the query in from the view:
def results(request):
return render_to_response('results.html', {'query': 'some query'})
But more than that, you need to get the actual results from Haystack and put those in context too. I think you are confused about what's happening here. If you want to use haystacks default views for search/results, then you shouldn't define any custom views at all. The way your results view is defined, how is Django to know this page has anything to do with Haystack at all?
If you do want to define custom views, then those views need to implement Haystack search forms, creation of SearchQuerySets, pagination, (and so on), and pass that data to the template. See the Haystack documentation on creating you own views:
http://django-haystack.readthedocs.org/en/latest/views_and_forms.html#creating-your-own-view
If you just want to see your results and this particular URL structure is not important to you, then just change your form action to point at the same page action="" and move your results display logic from results.html to search.html. That should get you the basic search results that ship with Haystacks default views and forms.