within an app I have two models, named Course and Step. Every Step belongs to a Course and each Course has many steps. However, I'm having problem creating a detailview for Steps. For example when i go to the url 'http://127.0.0.1:8000/courses/1' it should display steps for course.objects.get(pk=1). However what i get back is just the page for course, i.e, http://127.0.0.1:8000/courses'.
Model
from django.db import models
# Create your models here.
class Course(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length= 255)
description = models.TextField()
def __str__(self):
return self.title
class Step(models.Model):
title = models.CharField(max_length = 255)
description = models.TextField()
order = models.IntegerField()
course = models.ForeignKey(Course)
def __str__(self):
return self.title
Url
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.course_list),
url(r'(?P<pk>\d+)/$', views.course_detail)
]
View
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
from .models import Course, Step
def course_list(request):
courses = Course.objects.all()
return render(request, 'courses/course_list.html', {'courses': courses})
def course_detail(request, pk):
course = Course.objects.get(pk=pk)
return render(request, 'courses/course_detail.html', {'course': course})
course_detail.html
{% extends 'layout.html' %}
{% block title %}{{course.title}}{% endblock %}
{% block content %}
<article>
<h2>{{ course.title }} %</h2>
{{course.description}}
<section>
{% for step in course.step_set.all %}
<h3>{{ step.title }}</h3>
{{step.description}}
{% endfor %}
</section>
</article>
{% endblock %}
Main Urls
from django.conf.urls import url, include
from django.contrib import admin
from courses.views import course_list
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns = [
url(r'^courses/', course_list),
url(r'^admin/', admin.site.urls),
url(r'^$', views.hello_world),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
I just can't seem to recognize where i went wrong
I think the you need these url mappings..! This should do the trick.
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^applicationName/$', views.ListView.as_view(), name='courses'),
url(r'^applicationName/(?P<pk>\d+)$', views.CourseDetailView.as_view(), name='course-detail'),
]
The problem is in your main urls.py file - this line makes any URL path starting with 'courses/' resolve to the course_list view:
url(r'^courses/', course_list),
So Django will never reach the course_detail view. Instead, you must "include" the application-specific URLs:
url(r'^courses/', include('myproject.myapp.urls'),
Where myproject is your main project name, and myapp is your app name (make sure you also registered your application under INSTALLED_APPS at your settings.py file).
Related
I am trying to link two pages. Page files are home.html and pageOne.html. I am getting "NoReverseMatch at /'blog' is not a registered namespace". I am using django. When I first created the app, I named it artclBlog, I then created a templates folder and another folder within that one, this one I named blog. I think I should have kept these two names the same, this may have caused some confusion in my code.
pic of error
my views.py
from django.shortcuts import render, get_object_or_404
from .models import Blog
def home(request):
blogs = Blog.objects.order_by('-date')
return render(request, 'blog/home.html', {'blogs': blogs})
my urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from artclBlog import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('<int:blog_id>/', views.PageOne, name='PageOne')
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
my models.py
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=200, default='')
summary = models.CharField(max_length=200, default='')
pageOne = models.TextField(default='')
pageTwo = models.TextField(default='')
pageThree = models.TextField(default='')
pageFour = models.TextField(default='')
date = models.DateField(default='')
def __str__(self):
return self.title
home.html
{% for blog in blogs %}
<a href="{% url 'blog:PageOne' blog.id %}">
<h2 id="txt">{{ blog.title }}</h2>
</a>
<h4 id="txt">{{ blog.date|date:'M d y' }}</h4>
<p id="txt">{{ blog.summary|truncatechars:190 }}</p>
<hr>
{% endfor %}
You did not define an app_name in your urls.py, hence that means that blog: in blog:PageOne makes no sense. You thus either define an app_name, or remove the namespace.
Option 1: Add an app_name in urls.py
You can specify the namespace by writin an app_name in the urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from artclBlog import views
app_name = 'blog'
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('<int:blog_id>/', views.PageOne, name='PageOne')
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
This however means that thus all views now use this namespace, including home for example.
Option 2: Remove the namespace
Another option is to remove the namespace in the {% url … %} template tag [Django-doc]:
{% for blog in blogs %}
<a href="{% url 'PageOne' blog.id %}">
<h2 id="txt">{{ blog.title }}</h2>
</a>
<h4 id="txt">{{ blog.date|date:'M d y' }}</h4>
<p id="txt">{{ blog.summary|truncatechars:190 }}</p>
<hr>
{% endfor %}
This mistake comes usually when you have created different apps in your project.
First you do:
django-admin startproject mainapp
Then you do
python manage.py startapp secondapp
urls.py in your secondapp folder would automatically have app_name = 'secondapp'. However you must add in mainapp urls.py the following:
urlpatterns = [
...
path('secondapp/',include('secondapp.urls',namespace='secondapp')),
...
]
This is because your mainapp is the one that has the main access to the project and needs to know your secondapp urls.
i have one project andromeda where is 2 apps. 1 is blog and seccond one is blogmenu
but when I want to get information from the blog app there is no problem and i can get all information. but when I want to get a menu item from blogmenu I'm getting now error but there is empty navigation bar.
blogmenu urls.py
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
path('', include('blogmenu.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
blogmenu views.py
from django.shortcuts import render
def Blog_Menu(request):
Menu_items = Menu.objects.all()
template_name = 'front/index.html'
return render(request, template_name, {"Menu_items":Menu_items})
blogmenu models.py
from django.db import models
class Menu(models.Model):
Menu_name = models.CharField(max_length=100,blank=True)
Menu_slug = models.SlugField(name="სლაგი",blank=True)
Menu_image = models.ImageField(upload_to="menuimages")
Menu_url = models.CharField(name="url",max_length=100,blank=True,null=True)
class Meta:
verbose_name = "მენიუ"
def __str__(self):
return self.Menu_name
sample html template code
{% for menu in Menu_items %}
<li class="main-menu-item">
just text
</li>
{% endfor %}
When iteration items in loop you should post something. You can do the below in your template.
{% for menu in Menu_items %}
<li class="main-menu-item">
{{ menu.Menu_name }}
</li>
{% endfor %}
Seems to me that you just forgot to use the object from the for loop.
This is probably what your looking for:
{% for menu in Menu_items %}
<li class="main-menu-item">
{{ menu.Menu_name }}
</li>
{% endfor %}
If this isn't working either then I would suggest putting a print(Menu_items) after you make the query in your blogmenu views.py and see if your getting your data there.
Also don't forget to import your model in your views.py.
I just started with a Django project using django-allauth, I configured the basic settings, without using any 3rd party provider. I have set up the urls.py of my project and urls.py of my app.
But on going to http://localhost:8000, I am getting to 'home.html' but how do I remove the navigation of allauth
The following is the urls.py of my project :
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('allauth.urls')),
path('ckeditor/',include('ckeditor_uploader.urls')),
path('',include('blog.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
And this my urls.py of app :
from django.urls import path, include
from . import views
urlpatterns = [
path("", views.PostListView.as_view(), name = 'post_list'),
path("post/add", views.CreatePostView.as_view(), name = "create_new_post"),
]
views.py
from django.shortcuts import render
from django.views.generic import ListView, View
# Create your views here.
from .forms import PostForm, CommentForm
from .models import Post, Comment
class PostListView(ListView):
queryset = Post.objects.filter(is_published=True)
template_name = 'home.html'
class CreatePostView(View):
form_class = PostForm()
template_name = 'create_post.html'
model = Post
home.html
{% extends 'base.html' %}
{% block content %}
<h1>Hello World</h1>
{% for post in post_list %}
<h1>{{post.post_title}}</h1>
<p>{{post.post_body|safe}}</p>
{% endfor %}
{% endblock %}
path("post/add/", views.CreatePostView.as_view(), name = "create_new_post"),
add trailing slash to your url
your global urls.py:
path('',include('blog.urls')),
add something in your app urls.py:
path('test/',views.PostListView.as_view()),
after adding this to your urls.py, run your app again
the extended base.html file may contain the navigation. make changes there to remove or simply remove it
{% extends 'base.html' %}
I'm building a new site in Django with Django-CMS that needs a form to filter JSON results and return the filtered set.
My issue is that, initially, I can't even get the Django Model Form to render yet I can get the CSRF token to work so the form is technically rendering, but the inputs/fields aren't showing up at all.
models.py:
from django.db import models
from .jobs.jobs import *
roles = get_filters()
loc = roles[0]
j_type = roles[1]
industry = roles[2]
class Filter(models.Model):
country = models.CharField(max_length=255)
job_type = models.CharField(max_length=255)
industry = models.CharField(max_length=255)
search = models.CharField(max_length=255)
jobs/jobs.py
try:
from BeautifulSoup import BeautifulSoup
except ImportError:
from bs4 import BeautifulSoup
import urllib3
import json
http = urllib3.PoolManager()
def get_filters():
response = http.request('GET', 'http://206.189.27.188/eo/api/v1.0/jobs')
jobs = json.loads(response.data.decode('UTF-8'))
job_list = []
for job, values in jobs.items():
job_list.append(values)
roles_data = []
for job in job_list[0]:
roles_data.append(job)
roles_data = sorted(roles_data, key=lambda role : role["id"], reverse=True)
loc = []
j_type = []
industry = []
for role in roles_data:
loc.append(role['location'])
j_type.append(role['type'])
industry.append(role['industry'])
return loc, j_type, industry
views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import FilterForm
def index(request):
form = FilterForm()
context = {
'form': form,
}
return render(request, 'blog.html', context)
forms.py
from django.forms import ModelForm
from .models import Filter
class FilterForm(ModelForm):
class Meta:
model = Filter
fields = ['country', 'job_type', 'industry', 'search']
urls.py
from __future__ import absolute_import, print_function, unicode_literals
from cms.sitemaps import CMSSitemap
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.contrib.sitemaps.views import sitemap
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.views.static import serve
from . import views
admin.autodiscover()
urlpatterns = [
url(r'^sitemap\.xml$', sitemap,
{'sitemaps': {'cmspages': CMSSitemap}}),
url(r'^accounts/', admin.site.urls),
url(r'^services/latest-roles/', views.filter_form, name="filter_form" )
]
urlpatterns += i18n_patterns(
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'^', include('cms.urls')),
)
# This is only needed when using runserver.
if settings.DEBUG:
urlpatterns = [
url(r'^media/(?P<path>.*)$', serve,
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
] + staticfiles_urlpatterns() + urlpatterns
blog.html
{% extends 'includes/templates/layout.html' %}
{% load cms_tags i18n sekizai_tags zinnia %}
{% block main_content %}
{% include 'components-header-image.html' %}
<section class="module">
<div class="container">
<div class="row">
<div class="col-md-12 m-auto text-center">
<form action="POST" class="col-md-12">
{% csrf_token %}
{{ form.as_p }}
<button name="submit" class="btn btn-brand">Search</button>
</form>
{% get_all_roles%}
</div>
<div class="col-md-12">
<div class="space" data-MY="120px"></div>
</div>
<div class="col-md-12 flex-center text-center">
{% placeholder 'jobs-bottom-statement' %}
</div>
</div>
</div>
</section>
<!-- Image-->
{% include 'components-contact.html' %}
<!-- Image end-->
{% endblock %}
Sorry for the masses of information, just wanted to include anything anyone might need.
As I said, the CSRF token is displaying, nothing is throwing an error anywhere but it's just not displaying the fields at all.
Really appreciate any help or advice.
I'm 95% sure your view isn't being called.
You need to integrate your application as a CMS apphook or hard code your URLs into your root urls.py which is the easier integration test as it doesn't depend on CMS integration.
So Add your view to your URLs like this;
urlpatterns += i18n_patterns(
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'^blog/$', views.index, name='blog'),
url(r'^', include('cms.urls')),
)
Then go to localhost:8000/blog/ in your browser & you should hit your view.
To confirm you're hitting it you could make a simple amendment to your view;
def index(request):
form = FilterForm()
context = {
'form': form,
}
print "index hit"
return render(request, 'blog.html', context)
Then you'll see "index hit" in your console if your view is called.
So far I have been able to Create a project and setup a Homepage. So far I have had success with styling the page and getting my nav areas setup. I have also created an app that pulls a list of category names from my database and displays it in a right-justified list. When I point my browser to the app url, it works perfectly, but when I try to include the view in my project it displays the base panel with an error, and the dictionary I passed to the view does not appear to be available.
This is what I get when I load the home url localhost:8000/ in my browser:
This is what I get when I load the app url localhost:8000/categories/ in my browser:
Why am I not able to push the results of my app into my template? Both appear to work but not together?
base_right_panel.html
{% block content %}
<div style="float: right;">
<div id="base_categories" style="margin: 10px; padding-bottom: 10px;">
{% block base_categories %}
{% include "base_categories.html" %}
{% endblock %}
</div>
</div>
{% endblock %}
base_categories.html
{% block content %}
<div class="section" style="float: right;">
<h4 class="gradient">Category List</h4>
<ul>
{% if categories %}
{% for category in categories %}
<li>{{ category.title }}</li>
{% endfor %}
{% else %}
<p>no data! {{ categories|length }}</p>
{% endif %}
</ul>
</div>
{% endblock %}
CategoryList/views.py
from django.views.generic import TemplateView
from CategoryList.models import CategorylistCategorylist #<-- Changed to match inspectdb result
class IndexView(TemplateView):
template_name="base_categories.html" #<-- Changed name from index.html for clarity
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context["categories"] = CategorylistCategorylist.objects.all()
return context
CategoryList/models.py
from django.db import models
class CategorylistCategorylist(models.Model): #<-- Changed to match inspectdb
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255L, unique=True)
base_url = models.CharField(max_length=255L, unique=True)
thumb = models.ImageField(upload_to="dummy", blank=True) #<-- Ignored inspectdb's suggestion for CharField
def __unicode__(self):
return self.name
# Re-added Meta to match inspectdb
class Meta:
db_table = 'categorylist_categorylist'
CategoryList/urls.py
from django.conf.urls.defaults import patterns, url, include
from django.contrib import admin
from django.conf import settings
from CategoryList import views
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='base_categories'),
)
if settings.DEBUG:
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
url(r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns
MySite/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
from home import views as home_view
from CategoryList import views as index_view
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', home_view.HomeView.as_view(), name="home"),
url(r'^categories/$', index_view.IndexView.as_view(), name='base_categories'),#include('CategoryList.urls')),
url(r'^admin/', include(admin.site.urls)),
#url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
)
if settings.DEBUG:
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
url(r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns
I have another open question which has the relevant code examples but the question differs from what I am asking here.
Is there a simple way to display mysql data in Django template without creating an app?
You need to add the category queryset to your context in your HomeView. Remember, the view uses the templates to build the response - including a template that you also use in a different view (IndexView) does not cause any interaction with IndexView.
HomeView produces its response by rendering a template. If that template uses {% include %} tags to pull in pieces of other templates, those pieces will be rendered using the context established by HomeView. Nothing you do in IndexView has any effect on HomeView, and vice versa.
Continuing to reason by analogy to string interpolation, pretend your templates are global string variables instead of files on disk. Your situation is something like this:
base_categories = "My categories are: %(categories)s."
base_right_panel = "This is the right panel. Here are other fields before categories."
Using the {% include %} tag is something like string concatenation:
base_right_panel = base_right_panel + base_categories
Then your two views are analogous to this:
def home_view(request):
context = {}
return base_right_panel % context
def index_view(request)
context = {'categories': ['a', 'b', 'c']}
return base_categories % context
Unless you add the categories queryset to the context in HomeView, it will not be available to the template engine when rendering the response.
Your HomeView class should include the get_context_data method that you currently have in your IndexView. I am not sure you actually need IndexView at all, unless you want to have something that serves that page with just the categories list.