Django Create multiple views - python

I am new to Django. I have to create multiple views and create buttons for them in the main page. I have created different view for different filters of the table. I now have to create buttons in main page to redirect to different views . Can't figure the changes in urls.py and templates.
here is my code :
views.py
from django_tables2 import SingleTableView
from django.db.models import Max
from django.db.models import Min
from .models import airdata
from .tables import AirdataTable
class AirdataListView(SingleTableView):
model = airdata
table_class = AirdataTable
template_name = 'dashboard/data.html'
q = airdata.objects.aggregate(alpha=Min('pol_max'))['alpha']
queryset = airdata.objects.filter(pol_min= q).order_by('-state')
class AirdataListView2(SingleTableView):
model = airdata
table_class = AirdataTable
template_name = 'dashboard/data2.html'
q = airdata.objects.aggregate(alpha=Max('pol_max'))['alpha']
queryset = airdata.objects.filter(pol_min= q).order_by('-state')
app/urls.py
from django.urls import path
from . import views
from .views import AirdataListView,AirdataListView2
urlpatterns = [
path('page1/', AirdataListView2.as_view()),
path('page2/', AirdataListView.as_view()),
]
project/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('dashboard/', include('dashboard.urls')),
path('admin/', admin.site.urls),
]
template
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<title>Air Data</title>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
</head>
<body>
{% render_table table %}
</body>
</html>

Django will try to match the given url with one of the paths defined in urls.py.
In your case, you have two views that match the empty pattern, so Django is returning the first match and you wont be able to access your second pattern.
Try this on your urls.py:
urlpatterns = [
path('page1/', AirdataListView2.as_view()),
path('page2/', AirdataListView.as_view()),
]
Chances are you will eventually want to do more complex stuff and pass parameters into your urls so perhaps its a good idea to check the docs for more info about them.

Sure, as Django will run the first view match the url pattern which is the first one in your case. The problem you are handling can be solved by GET parameters. So read about it.

Related

Routing for FormView Class

I have django_test project and defapp application in it.
I want to access form.html which MyView makes,
I am still confused about routing.
I can access localhost/defapp/ and show Hello, World
However how can I access the MyView class and show form.html?
in django_test/urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include,url
urlpatterns = [
path('defapp/', include('defapp.urls')),
url(r'^s3direct/', include('s3direct.urls')),
path('admin/', admin.site.urls),
]
in defapp/views.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
]
in defapp/views.py
from django.shortcuts import render
# Create your views here.
from django.views.generic import FormView
from .forms import S3DirectUploadForm
def index(request):
return HttpResponse("Hello, world.")
class MyView(FormView):
template_name = 'form.html'
form_class = S3DirectUploadForm
in defapp/template/form.html
<html>
<head>
<meta charset="utf-8">
<title>s3direct</title>
{{ form.media }}
</head>
<body>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
</form>
</body>
</html>
If you're looking to know how to wire up a class based view in the urlconf, please checkout these docs on class based views.
The most direct way to use generic views is to create them directly in your URLconf. If you’re only changing a few attributes on a class-based view, you can pass them into the as_view() method call itself:
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('about/', TemplateView.as_view(template_name="about.html")),
]
Additionally, the docs on as_view may prove helpful.

Class views in Django, Html not showing

I'm confused with why my HTML template is not showing up.
I'm trying to learn Class base views instead of functions on Django.
I know the URL is working because {% extend base.html %} is showing, but anything else like the h1 tags aren't showing up in the render?
Can anyone help please.
views.py
from django.shortcuts import render
from django.views import View
from django.views.generic import (
CreateView,
DetailView,
ListView,
UpdateView,
ListView,
DeleteView
)
from .models import Article
class ArticleListView(ListView):
template_name = 'article/article_list.html'
queryset = Article.objects.all()
url.py
from django.contrib import admin
from django.urls import path
from .views import (
ArticleListView
)
app_name = 'article'
urlpatterns = [
path('', ArticleListView.as_view(), name = 'article_list'),
article_list.html
{%extends 'base.html'%}
<h1> Test </h1>
<h1> Test </h1>
{%block content%}
{% for instance in object_list %}
<p>{{instance.id}} - <a href = '{{instance.get_absolute_url}}'> {{instance.title}} </a></p>
{%endfor%}
{%endblock%}
[This is the outcome when i request get html, The current html is coming from base.html][1]
[1]: https://i.stack.imgur.com/W09EE.png
Use this code in the view:
context_object_name = 'article'
model = models. Article
And use this is in the template:
article. Id
{{article.get_absolute_url}}

How to change URLs based on a column data from the Database

I tried a lot but I am just not able to reach the exact solution.
I want to change the URLs of the list which is being generated by a for loop in HTML.
Here is my code for that view in views.py file:
class DashboardHomeViewClass(View):
def get(self, request, *args, **kwargs):
device_objects = device_user_data.objects.filter(User_Name = request.user.username)
device_list = []
for device in device_objects:
device_list.append(device.Device_Alias_Data)
context_logged = {'device_list': device_list}
return render(request, "dashboardhometemplate.html", context_logged)
Here is the code where this context is being used in the HTML template:
{%for item in device_list%}
<li> <i class="fa fa-bar-chart"></i><span class="hide-menu">{{item}}</span>
{% endfor %}
Now what I need exactly is: Different links should open on clicking different list view items based on device_Alias_Data.
eg : http://127.0.0.1:8000/dashboard/{{Device_Alias_Data}}
where Device_Alias_Data is character varying field in a table named device_user_data in my database.
Here is my urls.py file :
from django.conf.urls import url
from django.contrib import admin
from dashboardhome.views import DashboardHomeViewClass
from dashboardhome.views import login_view
from django.contrib.auth.views import login
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/$', login ,{'template_name': 'login_template.html'}),
url(r'^dashboard/$', DashboardHomeViewClass.as_view()),
]
First you should make some tweaks to your urls.py file for this to work:
app_name = "dashboardhome"
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/$', login ,{'template_name': 'login_template.html'}),
url(r'^dashboard/$', DashboardHomeViewClass.as_view(), name="dashboard"),
]
Here we added app_name and name attribute of the url method, this way we can make use of Django Reverse Resolution of urls
After that you can use template builtin url tag, like this:
{%for item in device_list%}
<li> <i class="fa fa-bar-chart"></i><span class="hide-menu">{{item}}</span>
{% endfor %}
And this gonna result in a url like this:
http://127.0.0.1:8000/dashboard/{{item}}
Make sure to check out the links for more info.
I hope this will help.
can use def get_absolute_url() method in model.py by importing django.url.reverse
and using url name.

NoReverseMatch at /polls/top/ 'polls' is not a registered namespace

Parent app name is mysite,child app name is polls.
I wrote in views.py
from django.shortcuts import render
from .models import Polls
def top(request):
data = Polls.objects.order_by('-created_at')
return render(request,'index.html',{'data':data})
def detail(request):
data = Polls.objects.order_by('-created_at')
return render(request,'detail.html',{'data':data})
in child app's urls.py
from django.conf.urls import url
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns=[
url('top/', views.top, name='top'),
url('detail/<int:pk>/', views.top,name='detail'),
]
in parent app's urls.py
from django.contrib import admin
from django.conf.urls import url,include
app_name = 'polls'
urlpatterns = [
url('admin/', admin.site.urls),
url('polls/', include('polls.urls')),
]
in index.html
<main>
{% for item in data %}
<h2>{{ item.title }}</h2>
<a href="{% url 'polls:detail' item.pk %}">SHOW DETAIL
</a>
{% endfor %}
</main>
When I access top method, NoReverseMatch at /polls/top/
'polls' is not a registered namespace error happens.I am using Django 2.0,so I think namespace cannot used.I wrote app_name ,so I really cannot understand why this error happens.How should I fix this?What is wrong in my code?
The var app_name should be inside polls.urls not in the urls.py parent's file. Also if you want to use the new routing that Django provides remember add the path module:
from django.urls import path
path('detail/<int:pk>/', views.top,name='detail'),
If you're using the url module check this and be careful with what version you're using https://docs.djangoproject.com/en/2.0/topics/http/urls/

python Django repeat url many times

I'm a starter of Django1.10. I just started play around with it. I am trying to show an image on website.
This is myproject/settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
and myproject/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^poster/', include('poster.urls')),
url(r'^admin/', admin.site.urls ),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
myproject/app/views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Info
# give a set of summary of items
def index(request):
latest_item_list = Info.objects.all()
context = {'latest_item_list': latest_item_list}
return render(request, 'poster/index.html', context)
def detail(request, item_id):
return HttpResponse("This function will return detail info for items %s" % item_id)
myproject/app/models.py
from django.db import models
class Info(models.Model):
def __str__(self):
return self.info_text
info_text = models.CharField(max_length=50)
pub_date = models.DateTimeField('date published')
info_image = models.ImageField(upload_to='images/%Y%m/%d')
myproject/app/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
# ex:/poster
url(r'^$', views.index, name='index'),
# ex: /poster/5
url(r'^(?P<item_id>[0-9]+)/$', views.detail, name = 'detail'),
]
myproject/app/templates/app/index.html
{% if latest_item_list %}
<ul>
{% for item in latest_item_list %}
{{forloop.counter}}.{{ item.info_text }}
{% endfor %}
</ul>
{% else %}
<p>No poster are available.</p>
{% endif %}
If I run python manage.py runserver, and go http://127.0.0.1:8000/poster/. I can see one object I created before, when I click it, the url it points to get repeated many times
I believe there is something wrong in the url.py, but I am not sure. Can someone help?
First of all I think you are missing a forwardshals in your models.py on line :
info_image = models.ImageField(upload_to='images/%Y%m/%d')
Unless it's your intention, I think it should be like this:
info_image = models.ImageField(upload_to='images/%Y/%m/%d')
^
Next thing is that you are not providing the right url for href attribute in the <a> tag of your index.html template.
{{forloop.counter}}.{{ item.info_text }}
This line will point to the image itself. So you can use it example in the <image src="{{ item.info_image.url }}" /> but not in a link tag. So I guess this is what you were looking for.
To point to your detail view of specific image you would want to ideally create get_absolute_url method on your Info model class.
Model.get_absolute_url()
Define a get_absolute_url() method to tell Django how to calculate the canonical URL for an object. To callers, this method should appear to return a string that can be used to refer to the object over HTTP.
For example:
# models.py
class Info(models.Model):
...
info_image = models.ImageField(upload_to='images/%Y%m/%d')
def get_absolute_url(self):
return reverse('detail',
args=[self.id])
Then you could use that in your template like this:
{{forloop.counter}}.{{ item.info_text }}
and display your image, wherever you want, using:
<image src="{{ item.info_image.url }}" />
Have you checked how the URL looks in the generated HTML code? E.g. does the URL look correct when the HTML is loaded, and when you click it, it starts repeating it?

Categories