python Django repeat url many times - python

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?

Related

Django admin page written text is not displaying on web page

Ignore the title. I got problem on displaying text written and save on admin page.
I just create new app with name about. using command python manage.py startapp about
and all the below files are inside this app.
Models.py
from django.db import models
# Create your models here.
class About(models.Model):
title = "About me"
discription = models.TextField()
def __str__(self):
return self.title
admin.py
from django.contrib import admin
from .models import About
# Register your models here.
admin.site.register(About)
# Register your models here
views.py:
from django.shortcuts import render
from django.http import HttpRequest
from .models import About
# Create your views here.
def about(request):
abouts = About.objects.all()
return render(request, 'about/about.html', {'abouts': abouts})
urls.py
from django.urls import path
from . import views
app_name = 'about'
urlpatterns = [
path('', views.about, name='about'),
]
about.html
<p style="color: white;">{{ abouts.discription }}</p>
Problem is that the text written inside discription didn't showing on about.html page. please help me.
{{ abouts }} is a queryset. The following code iterates over each item inside the queryset, thus creating a list.
<ul>
{% for about in abouts %}
<li>{{ about.description }}</li>
{% endfor %}
</ul>

How to Increment Next Record in Django / Templates

In index.html - I am able to read the first item of my table / model in Django just fine with my code below. However, after the user clicks the next button - I want it to retrieve the next item of my table / model. (how / where do I build this counter?)
here is views.py
def index(request):
flash_dict = {'flashcards': Card.objects.get(pk=1)}
return render(request, 'flash/index.html', context=flash_dict)
here is index.html
<div class = "jumbotron">
{% if flashcards %}
<p class = 'question'>{{ flashcards }}</p>
<p class = 'answer'>{{ flashcards.flash_answer }}</p>
<button type="button" class="btn btn-primary" onclick = "flip()">Flip</button>
<button type="button" class="btn btn-primary">Next</button>
{% else %}
<p>NO ACCESS RECORDS FOUND!</p>
{% endif %}
</div>
here is models.py
from django.db import models
# Create your models here.
class Card(models.Model):
flash_question = models.TextField()
flash_answer = models.TextField()
objects = models.Manager()
def __str__(self):
return self.flash_question
here is urls.py (under base project folder)
from django.contrib import admin
from django.urls import path, include
from flash import views
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index,name='index'),
]
here is urls.py (under app folder)
from django.conf.urls import url
from flash import views
urlpatterns = [
url(r'^$', views.index, name='index')
]
The semantically 'correct' way to make this work is by rewiring your code significantly:
First, you need to modify urls.py, in your base folder, so that the flashcard URL takes a flashcard ID. This will allow you to visit flashcard/1/, flashcard/2/, etc. and see data for the corresponding flashcard.
urls.py
from django.contrib import admin
from django.urls import path, include
from flash import views
urlpatterns = [
path('admin/', admin.site.urls),
path('flashcard/<int:card>/',views.index,name='flashcard'), # Here we are adding a variable to the URL pattern, which will be passed to the view
]
Next, you need to modify your view so that it takes a flashcard ID from the URL and renders the flashcard in question:
views.py
def flashcard(request, card=1): # Your view will now look for the 'card' variable in your URL pattern.
flash_dict = {'flashcards': Card.objects.get(pk=card)} # Your 'flashcards' variable now holds the card that corresponds to the ID in the URL
return render(request, 'flash/index.html', context=flash_dict)
Then, we'll write a method within your Card model that will pull the next card when self.get_next is called. Now, if you have a Card object, you can find the next card by calling card.get_next():
models.py
from django.db import models
# Create your models here.
class Card(models.Model):
flash_question = models.TextField()
flash_answer = models.TextField()
objects = models.Manager()
def __str__(self):
return self.flash_question
def get_next(self):
next = Card.objects.filter(id__gt=self.id).order_by('id').first()
if next:
return next
# If the current card is the last one, return the first card in the deck
else:
return Card.objects.all().order_by('id').first()
Finally, we'll replace the buttons in your template with an a href that links to the new 'flashcard' view, and passes it the ID of the next card in the sequence:
template.html
<div class = "jumbotron">
{% if flashcards %}
<p class = 'question'>{{ flashcards }}</p>
<p class = 'answer'>{{ flashcards.flash_answer }}</p>
<!-- Here we link to the 'flashcard' view, and pass it the ID of the next card in the sequence -->
Next flashcard
{% else %}
<p>NO ACCESS RECORDS FOUND!</p>
{% endif %}
</div>
Now, try visiting /flashcard/1 to see how everything works together.

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.

How to manipulate database info before displaying it in Django template?

So I've got a basic Django website setup that displays dynamic info from the database.
I would like to be able to manipulate the text coming out of the database so I can create BBCode parsers or whatever else I want. I'm pretty new to Django so I'm a little confused as to where this should be done.
These are my files so far...
Models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=140)
body = models.TextField()
date = models.DateTimeField()
def __str__(self):
return self.title
Urls.py
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from forum.models import Post
urlpatterns = [
url(r'^$', ListView.as_view(queryset=Post.objects.all().order_by("-date")[:25], template_name="forum/forum.html")),
url(r'^(?P<pk>\d+)$', DetailView.as_view(model = Post, template_name = 'forum/post.html')),
]
Forum.html
{% extends "layout.html" %}
{% block body %}
{% for post in object_list %}
<p>{{ post.date|date:"Y-m-d" }} {{ post.title }}</p>
{% endfor %}
{% endblock %}
Functions.py
def bbcode(data):
data2 = data + "some random text"
return data2
All of those files are located inside of the "forum" directory located in the root project folder which is "coolsite".
So my understanding is that I need to import functions.py somewhere and use the bbcode() method to manipulate text being pulled from the database. That way it has been parsed once displayed on the "forum.html" template.
Sorry if this is a duplicate question. I searched around and couldn't quite find what I was looking for.
How should I go about doing this exactly?
You need to override the ListView methods. You will need to do some changes in your code:
Set a custom view to your url config
urls.py
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from forum.models import Post
from forum.views import PostList
urlpatterns = [
url(r'^$', PostList.as_view(), name='post_list'),
url(r'^(?P<pk>\d+)$', DetailView.as_view(model = Post, template_name = 'forum/post.html')),
]
Create a custom view in your app (forum.views) based in a ListView
# views.py
from django.views.generic import ListView
from forum.models import Post
class PostList(ListView):
model = Post
template_name = "forum/forum.html"
# here is where magic happens
def get_context_data(self, *args, **kwargs):
context = super(PostList, self).get_context_data(*args, **kwargs)
# context has the same context that you get in your template before
# so you can take data and work with it before return it to template
return context
You can found docs for Class-Based Views here

Content not showing up on detailed view in Django

UPDATE #1:
I'm still having some issues, I'm getting some of the content using tags like {{object.title}}, but content that I've included using {% include "sidebar.html" %} and {% include "slider.html" %} are not showing up.
Part of my sidebar.html looks like this:
<div class="navItem">
<div class="overlay">
</div><!-- /.overlay -->
<img src="{{article.relatedImage}}" alt="" class="navPicture">
<p class="navTitle">{{article.title|truncatewords:"4"}}</p>
</div><!-- /.navItem -->
I'm doing a class assignment and I'm using the same tags as I have on my main page on my detailed page in Django, but the actual content on the detailed page is not showing up when I use the {{tags}}.
Snippet of detailed.html
<p class="date">{{article.pubDate|date:"l, F j, Y" }}</p> | {{article.author}}
<img src="{{article.heroImage}}" alt="" class="largeImage">
<div class="contentBlock">
<img src="{{article.relatedImage}}" alt="" class="relatedImage">
views.py
from django.views import generic
from . import models
# Create your views here.
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns(
'',
url(r'^$', views.BlogIndex.as_view(), name="list"), url(r'^(?P<slug>\S+)$', views.BlogDetail.as_view(), name="detailed"),
)
Screenshot of list.html: http://imgur.com/vygVAkj
Screenshot of detailed.html: http://imgur.com/umnCE27
You are using {{ article }} in your template. Which is undefined. Either user {{ object }}, either specify context_object_name = 'article' in your Detail View.
Moreover, you are using white spaces for identifying your objects??? i.e. you are doing stuff like models.FullArticle.objects.get(pk=' ') which is really weird.
Mihai zamfir was right.
Here's the full code - this should be in your views.py
class FoodDetail(DetailView)
model = FoodPost
context_object_name = 'post'
template_name = 'views/detail-views/food-details.html'
for urls.py
path('posts/<str:link>/<int:pk>', FoodDetail.as_view(), name="food-detail")
and inside details view
<h1>{{post.pk}}</h1>
and the template from which you are referring should be
read more

Categories