Django QuerySet not appearing in HTML file for PythonAnywhere Web App - python

I'm having a bit of trouble with this part of the DjangoGirls tutorial (about templates).
Currently, my website is at chocoberrie.pythonanywhere.com. It's supposed to show a few posts inside the QuerySet, but the list is empty, and I don't know why (or how to fix it).
1) The QuerySet isn't loading at all in the HTML file.
I followed the steps to import the Post model into views.py and add the QuerySet in the posts variable (the previous part of the tutorial). When I tried putting {{ posts }} in the HTML file (post_list.html), nothing appears in the QuerySet that loads on the page.
2) I don't know how to edit the database file on PythonAnywhere. This database file is supposed to be separate from the local db.sqlite3 on my computer (since db.sqlite3 is in the .gitignore file, it's not committed).
I read about this here. I understand that this is useful to keep production changes from being displayed on the live website, but how I supposed to have this data on the PythonAnywhere side? What file am I supposed to edit on PythonAnywhere?
Thanks for the help, I appreciate it!
Here are my local files:
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
]
views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
post_list.html
<html>
<head>
<title>Dina's blog</title>
</head>
<body>
<div>
<h1>Dina's Blog</h1>
</div>
{{ posts }}
</body>
</html>

you cant just use the query_list like that in the template, you need to loop through it in the template and it will show all posts titles so your template will be like this
{% for post in posts %}
<p>{{post.post_title}}</p>
{% endfor %}
i recommend following this blog

I don't know if you have already done it or not, but when actually creating the posts you will also have to save it. So for example:
Example form.py
from django import forms
class createPostForm(forms.Form):
title = forms.CharField(required = True)
detail = forms.CharField(required = True)
Example views.py
import models
def createPost(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
title = form.cleaned_data.get('title')
detail = form.cleaned_data.get('detail')
newPost = models.Post(title = title, detail = detail)
newPost.save()
return redirect('blog/post_list.html')
Otherwise you won't be able to access it, since your website will take the inputs in and it will look like a post was created if the fields were valid, but your posts won't actually get created and your database will be empty! Also get a database viewer so that you can see if the entries are actually there.

Related

Content of database not showing up in Django

I have some problems to get the content out of the django database.
I'm a bloody beginner at django so I did some tutorials. They've worked fine. Now I want to reproduce them in my own project with own variables so I can see if I've understood all the stuff.
So to come to my problem I initalized my modules in models.py
from django.db import models
class Aboutme(models.Model):
author = models.CharField(max_length=30)
...
This works because I could add content to the database.
So there is no mistake.
Now in the views.py
from django.shortcuts import render
from portfolio.models import Aboutme
def portfolio_index(request):
aboutme = Aboutme.objects.all()
context = {'aboutme': aboutme}
return render(request, 'portfolio_index.html', context)
So finally in my HTML file, called portfolio_index.html, I call the content via
<h1>{{ aboutme.author }}</h1>
I guess it's right. But the content of author doesn't showup, so what did I miss?
I can call static files via django, so couldn't be something wrong with django...
Can anyone help.
Thanks in advance.
I think that you need to use a for loop to show "aboutme" because with "aboutme = Aboutme.objects.all()" you query a list of elements.
{% for aboutme_item in aboutme %}
<h1>{{ aboutme_item.author }}</h1>
{% endfor %}

Django not serving text content (First attempt)

Summary:
The purpose of this particular Django web app is to just show some lorem ipsum text on the home page, like a blog post. Django is not serving my blog post content. I know the problem is either with my views.py or urls.py (or both).
Details:
I’ve got the data declared inside my models.py. I’ve got my views.py to instantiate the model. I migrated sqlite and successfully logged into the Admin Dashboard and entered some placeholder data.
I’m trying to get Django to serve the placeholder content that I entered into the Admin Dashboard, but instead it’s blank.
Here is my what my test case looks like: https://i.imgur.com/IuOl3G4.jpg
To describe it, you can see The Blog Post, Date, Image, and Body Text HTML heading elements parsed, but none of the content is showing.
Here is my app’s urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.mortems, name='home'),
]
I’ve tried swapping out the quotation marks for the first path() parameter with alls/landings. I’ve tried swapping the name parameter from home to mortems. I also tried using mortem (without the s). None of these changes help.
I've also tried Googling (with variations):
'body text django not showing template'
'django not showing text contents'
Which turned up (among other) SO questions and answers which kind of sound related but are completely different from my issue:
Django Message framework is not showing message in template
Why django template is not showing any output?
Here is my app’s views.py:
from django.shortcuts import redirect, render, get_object_or_404
from mortems.models import Mortem
def mortems(request):
mortem = Mortem.objects.order_by('-pub_date')
context = {'mortem':mortem}
return render(request, 'alls/landings.html', context)
For what it is worth, here are the relevant lines in my model:
class Mortem(models.Model):
title = models.CharField(max_length=161)
pub_date = models.DateTimeField()
image = models.ImageField(upload_to='media/')
body = models.TextField()
now = datetime.datetime.now()
Also, here is my template with the relevant problematic lines (42-50):
<h1> BLOG POST:</h1>
<h4>Date: {{ mortem.pub_date_preference }}</h4>
<br />
Image: <img src="{{ mortem.image.url }}" class="img-responsive center-block" style="max-height:300px;" />
<br />
<!-- Body text should go here : -->
Body Text:
<p>{{ mortem.body|safe }}</p>
The full source code is up on GitHub. Here is the 'mortems' app source code specifically.
For generous SO users with time on their hands, I guess I’m accepting pull requests. haha
I think you need to update the views.py as:
from django.shortcuts import redirect, render, get_object_or_404
from mortems.models import Mortem
def mortems(request):
mortems = Mortem.objects.all().order_by('-pub_date') # returns an iterable queryset
context = {'mortems':mortems} # using plural as it's a list like object
return render(request, 'alls/landings.html', context)
In the template code, you need to iterate over the list to display a single object one at a time. i.e
<h1> BLOG POSTs:</h1>
{% for moertm in mortems}
<h4>Date: {{ mortem.pub_date_preference }}</h4>
<br />
Image: <img src="{{ mortem.image.url }}" class="img-responsive center-block" style="max-height:300px;" />
<br />
<!-- Body text should go here : -->
Body Text:
<p>{{ mortem.body|safe }}</p>
{% endfor %}

Django to call the correct function

been searching a lot for fixing my issue.. New to django and might be missing a very simple logic here and looking for some help..
I have created a form in html page called thispage.html as below:
<form action="{% url 'getvaluefromform' %}" method="POST">{% csrf_token %}
<input type="text" name='mytitle' placeholder="enter title">
<input type="submit" value="save">
</form>
then I updated views.py with the below code:
from django.shortcuts import render
def index(request):
return render(request,'thispage.html')
def getvaluefromform(request):
mytitle = request.POST.get('mytitle')
print(mytitle)
return render(request,'thispage.html')
finally my urls.py has this part:
from dhango.urls import path
from . import views
urlpatterns = [
path('',views.index,name='index'),
path('getvaluefromform',views.getvaluefromform,name='getvaluefromform')
]
Problem:
when I use this I am able to get the input vallue however the url is changing to '/getvaluefromform' and when I remove 'getvaluefromform' from the url section and just keep it '' then the code view index gets picked up.
Is there a way I can call the second function when button is clicked without moving to the new path. Please advise.
P.S - I am deliberately not using a model form because I want to build a raw sql query based on user input and then run the query to get the results/ create a new table on the database.
Django forms:
If you want to get POST data from a form without changing routes you have a very good example in the official documentation.
HTML forms:
If you're not into Django forms you can do as stated below.
def getvaluefromform(request):
if request.method == 'POST':
mytitle = request.POST.get('mytitle')
return render(request,'otherpage.html')
return render(request,'thispage.html')
What this will do is basically check if there's a POST request, get the form data and if there's a GET request, you'll just render the defined page.
If you must have two different routes, I suggest using Javascript.

How to edit dict in views.py from django admin

I'm working on a site to better learn the Django-framework. I've currently set up views and links to template files to display content on the main page. In my views.py file I've added a dictionary that is displays the dict value for each key in in the index.html page when it gets rendered:
views.py:
def Index(request):
projectmessage = {
"projectMessage":"This is text from a dictionary value. written in views.py",
"projectTitle":"Title from dict",
"projectText": "Text from dict",
}
return render(request,'wbdev/index.html', context=projectmessage)
Relevant lines in index.html:
<h3>{{ projectTitle }}</h3>
<p>{{ projectMessage }}</p>
I'm wondering if this could be made visible on the django admin page so that I can change the dict text directly from the GUI. Could this be done or am I way off in the sense that this is not the intended for the django admin page? From what I've red django admin parses the models.py file to set up text fields and buttons. I've followed the official django tutorial and some of the "How to tango with django" book but I cant wrap my head around how I should proceed in getting the functions that I want.
I'm sorry for the noob question. I will return to my books and I will probably understand how this works down the line. If anyone could help me with an explanation of how I can achieve this I will be most grateful.
Thank you.
You'll probably want to create a Model for Projects, so projects can be saved to a Database and easily displayed in the Admin.
Inside models.py include the following:
class Project(models.Model):
message = models.CharField(max_length=20)
title = models.CharField(max_length=20)
text = models.CharField(max_length=20)
Inside admin.py if you register the model it should then appear in the admin
from dajngo.contrib import admin
from .models import Project
admin.site.register(Project)
Finally for your index in views.py you'll want to query the database for the project objects in question before rendering them to the template
def index(request):
projects = Project.objects.all()
return render(request,'wbdev/index.html', context={'projects': projects})
Inside your template you can then iterate over all the projects in your database like
{% for project in projects %}
{{ project.message }}
{{ project.title }}
{{ project.text }}
{% endfor %}

Get data from multiple django app models on single html page

I have a project called Project_Name and an app called first_app with some articles in it.
I am displaying these article titles on my home page as links to the articles which are on the app's page.
So at 127.0.0.1:8000/ I have index.html. Here I display the list of articles. Then if I click an article I go to 127.0.0.1:8000/first_app/1, to display the first article for example.
Here is my project-wide views.py:
...
from first_app.models import Article
def home(request):
latest_article_list = Article.objects.order_by('-pub_date')[:20]
context = {'latest_article_list': latest_article_list}
return render(request, 'index.html', context)
In my project-wide urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'Project_Name.views.home', name='home'),
url(r'^admin/', include(admin.site.urls)),
...
Here is my models.py inside my first_app application:
from django.db import models
from datetime import datetime
class Article(models.Model):
name = models.CharField(max_length=140)
content = models.CharField(max_length=1000)
pub_date = models.DateTimeField(default=datetime.now())
Here is my views.py inside my first_app application:
def article_detail(request, article_id):
art = get_object_or_404(Article, pk=article_id)
return render(request, 'first_app/detail.html', {'article': art})
Here is my detail.html inside my first_app templates folder:
<h2><u>{{ article.name }}</u></h2>
<b>Published On: </b>{{article.pub_date }}
<b>Content: </b>
<ul>
<li>{{ article.content }}</li>
</ul>
Here is my project homepage, index.html:
{% if latest_article_list %}
<h2>Latest Articles</h2>
<ul>
{% for article in latest_article_list %}
<li>{{article.name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No articles are available.</p>
{% endif %}
This is all working fine.
My Question:
If I had two or more apps, each with their own articles (I am breaking up the articles by different apps for other reasons), how would I get those articles on the home page? and how would I then build the urls so when I click an article from the home page it takes me to the correct app url?
So for example, I have apps: first_app, second_app, and third_app. Each app has several articles in it. I want my home page to display all of the articles from every app. If I click on an article from first_app (say the third article posted on first_app), I am directed to url 127.0.0.1:8000/first_app/3. Likewise, if I click on an article from the third_app (say the second article posted on third_app), I am directed to url 127.0.0.1:8000/third_app/2.
Im not sure how to iterate over all of my app's models to get the Article table's data. And im not sure how to generate urls to reflect the app which the articles came from. I have tried a few things but nothing works. Im stuck at this point.
I am pretty new to Django, so please give me some helpful comments or solutions rather then knock down my question.
How should I change my views, urls, and html pages to do this? Thanks.
For the URL question, use the get_absolute_url functionality on the models,
For the question about iterating all models in app, thats nothing you are ment to do in a template, you are supposed to gather the data you need in the view and present it to the template for rendering, so the answer is that you pick the models you need in your view, then send it to the template.
But apps are ment to be reusable components, and if your apps have a hard dependency on each other its hard to motivate them being separate apps.

Categories