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.
Related
I'm learning Chapter 18 in Python Crash Course by Eric Matthes. I am using Django 4.0.1 and the book uses is 2.2.0 so I see that other people are having similar issues as me with this section.
In other similar stackoverflow questions on this issue, proposed solutions using url instead of path seem also outdated. The solutions on the website therefore are unfortunately not helping me.
Problem:
when I open http://localhost:8000/ and I click on "topics" I get the 404 not found error as follows:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/(%25%20url%20'learning_logs:topics'%20%25%7D
Using the URLconf defined in learning_log.urls, Django tried these URL patterns, in this order:
admin/
[name='index']
topics/ [name='topics']
The current path, (% url 'learning_logs:topics' %}, didn’t match any of these.
However, navigating manually to http://localhost:8000/topics shows me the page as intended. I believe this is an issue due to my urls.py located in my app folder.
Here is my urls.py in learning_logs (app), where I think the issue lies:
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns = [
#Home page
path('', views.index, name='index'),
#Page that shows all topics.
path('topics/', views.topics, name='topics'),
]
Here is my urls.py in learning_log (main project):
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('learning_logs.urls')),
]
views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
"""The home page for Learning Log."""
return render(request, 'learning_logs/index.html')
def topics(request):
"""Show all topics."""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
base.html found in template/learning_logs folder:
<p>
<a href="{% url 'learning_logs:index' %}" >Learning Log</a> -
<a href="(% url 'learning_logs:topics' %}" >Topics</a>
</p>
{% block content %} {% endblock content %}
topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p> Topics </p>
<ul>
{% for topic in topics %}
<li> {{topic}}</li>
{% empty %}
<li> No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
and finally index.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Learning Log helps you keep track of your learning, for any topic you're
learning about.</p>
{% endblock content %}
The comment below my question by Willem Van Onsem answered my question, turns out it was a typo.
The Topics did not start the url template tagb with {%... –
Willem Van Onsem
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>
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.
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 %}
I am trying to create a blog. Home page of the blog will contain summary about the blog posts (ordered by date).
When the user clicks on the title of the blog post on the home page, page for that post should open up.
So I am trying to the above and running into some problems.
Here is what the post.html file looks like (file that would display full post) :
{% extends "base.html" %}
{%block content %}
<div class="mainContent">
<div class = "Content">
<article class = "Typical Article">
<header>
<h3>{{post.title}}.....{{post.id}}</h3>
</header>
<footer>
<p class = "postInfo">Sukhvir Notra, {{post.date}}</p>
</footer>
<content>
<p>{{post.summary|safe|linebreaks}}</p>
</content>
</article>
</div>
</div>
{%endblock%}
And here is the urls.py file inside my app:
from django.conf.urls import patterns,include ,url
from django.views.generic import ListView, DetailView
from blog.models import blog
urlpatterns = patterns('',
url(r'^$',ListView.as_view(queryset=blog.objects.all().order_by("-date")[:20],template_name="blog.html")),
url(r'^(?P<pk>\d+)$',DetailView.as_view(model = blog,template_name="post.html")),
url(r'^archives$',ListView.as_view(queryset=blog.objects.all().order_by("-date"),template_name="archives.html")),
url(r'^latestnews$',ListView.as_view(queryset=blog.objects.all().order_by("-date")[:10],template_name="archives.html")),
)
the problem is when I click on the title on the home page, New page opens up with correct url (127.0.0.1/blog/1 --- 1 being the post.id)
but the page is blank and all I see on the page is ...... which tells me that {{post.id}},{{post.title}} variables are not working properly.
What may be causing this issue ?
Set the context_object_name in your urls to the name you want your object to have in your template.
eg:
url(r'^(?P<pk>\d+)$',DetailView.as_view(model = blog,template_name="post.html", context_object_name="post")),
Django uses a default context object with the name object (for DetailView) or object_list (for ListView) unless otherwise specified.