How to Increment Next Record in Django / Templates - python

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.

Related

Django - Data from view not rendered in template

I'm having quite some troubles understanding how variables are passed to templates in Django, I'm new so keep this in mind.
My problem is that, when the URL is loaded data from databases can't be rendered except for the user(request.user.username) which is strangely loaded.
I even tried to declare variables inside the view's def but even them are not rendered
The model is imported inside the views.py.
My idea is that, since the user from request.user is loaded, there must be some problem with loading the database model, but this doesn't explain why even freshly declared variables inside the view's def are not passed.
In the /admin page all the models work fine.
Below are the fragments of my code, they should be enough to understand the problem, if not I can upload other parts.
Thank you in advance.
views.py:
def load_main(request):
diet_list = DietTable.objects.all()
return render(request, 'main/main.html',
{
'diet_list': diet_list,
'user': request.user.username,
})
part in the main.html:
<body>
...
<header>
...
</header>
...
{% block content %}
<strong>
{{ user }}
{% for element in diet_list %}
{{ element }}
{% endfor %}
</strong>
{% endblock %}
...
</body>
urls.py:
from django.urls import path, include
from main import views
urlpatterns = [
path('', views.load_main, name='main_view'),
]
models.py
...
class DietTable(models.Model):
diet_id = models.AutoField(primary_key=True) # to not use the default 'id; given by django
dietName = models.CharField(max_length=50)
dietType = models.ForeignKey(DietTypes, on_delete=models.PROTECT)
startDate = models.DateTimeField()
dayLength = models.IntegerField()
def __str__(self):
return str(str(self.dietName) + "(" + str(self.dayLength) + ")")
...

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>

Why won't my server start running?

Why am I getting an error when trying to run my server to access the database to see if my code works? While in my projects folder in Terminal, I ran sudo python manage.py runserver to try to run the server but it doesn't work because of the aforementioned error. I've looked around SO but can't find one directly related to my problem.
I'm guessing my if() statement is the problem.
The error I'm getting says:
RuntimeError: maximum recursion depth exceeded while calling a Python object
Here's my views.py file:
from .models import Album
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.core.urlresolvers import reverse_lazy
from django.views import generic
from django.views.generic import View
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .forms import UserForm
class IndexView(generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
return Album.objects.all()
class DetailView(generic.DeleteView):
model = Album
template_name = 'music/detail.html'
class AlbumCreate(CreateView):
model = Album
fields = ['artist', 'album_title', 'genre', 'album_logo']
class AlbumUpdate(UpdateView):
model = Album
fields = ['artist', 'album_title', 'genre', 'album_logo']
class AlbumDelete(DeleteView):
model = Album
success_url = reverse_lazy('music:index')
class UserFormView(View):
form_class = UserForm
template_name = 'music/registration_form.html'
# display blank form
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
#cleaned normalized data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
Here's the error:
File "/Library/Python/2.7/site-packages/Django-1.11.2-py2.7.egg/django/urls/resolvers.py", line 255, in check
warnings.extend(check_resolver(pattern))
File "/Library/Python/2.7/site-packages/Django-1.11.2-py2.7.egg/django/core/checks/urls.py", line 26, in check_resolver
return check_method()
File "/Library/Python/2.7/site-packages/Django-1.11.2-py2.7.egg/django/urls/resolvers.py", line 172, in check
warnings = self._check_pattern_startswith_slash()
File "/Library/Python/2.7/site-packages/Django-1.11.2-py2.7.egg/django/urls/resolvers.py", line 140, in _check_pattern_startswith_slash
regex_pattern = self.regex.pattern
Here's my forms.py file:
from django.contrib.auth.models import User
from django import forms
class UserForm(forms.ModelForm): # UserForm inherits from forms.
passwords = forms.CharField(widget=forms.PasswordInput)
class Meta: # Information about your class.
model = User # whenevr a creates sign up to your site it's gonna go in same table
fields = ['username', 'email', 'password']
Here's my urls.py file:
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
app_name = 'music'
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^music/', include('music.urls'))
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.MEDIA_ROOT)
Here's my album_form.html file:
{% extends 'music/base.html' %}
{% block title %}Add a New Album{% endblock %}
{% block album_active %}active{% endblock %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<form class="horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'music/form-template.html' %}
<div class="form-group">
<div class="col-sum-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Here's my index.html file:
{# loads path to static file #}
{% extends 'music/base.html' %}
{% block body %}
<ul>
{% for album in all_albums %}
<li>{{ album.album_title }}</li>
{% endfor %}
</ul>
{% endblock %}
I suspect you have a recursive reference from your include in music.urls to urls.py since the error that django throws is specific to URL resolver.
Your if statement has no error. 'music:index' refers to namespaced url names and still need named url statements in urls.py. Since in simple projects, there is only one application, the namespace is redundant. So in most cases, 'index' should be used instead, just like what I have show below.
In your urls.py, there is a include to music.urls, and it seems to be recursive reference to itself. 'music.urls' refers to the file urls.py in music directory.
If you do not have a valid python object for 'music.urls', then your include statement is wrong.
I do not use include urls in my project, so there will need to be a statement for each view defined in views.py. To test whether your server starts correctly, I would try the following urlpatterns. Don't forget to import IndexView and DetailView. Add more url statements for you other views after testing out 1 or 2 first.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^music/index/$', IndexView.as_view() , name='Index'),
url(r'^music/detail/(?P<pk>[0-9]+)/$', DetailView.as_view() , name='Detail'),
]
I use named url, and the statement in index.html should be written as follows:
{{ album.album_title }}
The namespace 'music:' is omitted since it is implicit and will look simpler. You should leave it out for simple applications as it may be confusing for beginners.

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?

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