I'm very new to Django and I've been learning the framework from the book "Practical django Projects" (the book teaches us to write a cms). My code runs fine, but I have time problem with the get_absolute_url function below. It's actually outputting the link 8 hours ahead of the time saved in my database. I used python shell to look at the saved time in the database and the time saved in the admin interface, they are all correct. But when I use the get_absolute_url func below to generate the link in browser, it becomes 8 hours ahead and throws the day off. I set the correct zone in my Django setting file. I cannot figure out what's wrong.
How I can fix this (I'm using sqlite3 for my database, Django 1.4.1)?
Here is my code for the Entry class:
import datetime
from django.db import models
from django.contrib.auth.models import User
from tagging.fields import TagField
from markdown import markdown
from django.conf import settings
from django.utils.encoding import smart_str
class Entry(models.Model):
live = LiveEntryManager()
objects = models.Manager()
#define constant options
LIVE_STATUS = 1
DRAFT_STATUS = 2
HIDDEN_STATUS = 3
STATUS_CHOICES = (
(LIVE_STATUS, 'Live'),
(DRAFT_STATUS,'Draft'),
(HIDDEN_STATUS, 'Hidden'),
)
#adding features to admin interface
class Meta:
ordering = ['-pub_date']
verbose_name_plural = "Entries"
#define model fields:
title = models.CharField(max_length=250)
excerpt = models.TextField(blank=True) #It's ok to not add anything for this field
body = models.TextField()
pub_date = models.DateTimeField(default=datetime.datetime.now())
slug = models.SlugField(unique_for_date='pub_date')
enable_comments = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
status = models.IntegerField(choices=STATUS_CHOICES, default=LIVE_STATUS)
#HTML
excerpt_html = models.TextField(editable=False, blank=True)
body_html = models.TextField(editable=False, blank=True)
#third party:
tag = TagField()
#relationship fields:
categories = models.ManyToManyField(Category)
author = models.ForeignKey(User)
#define methods:
def save(self, force_insert=False, force_update=False):#modify the model.save() method
self.body_html = markdown(self.body)
if self.excerpt:
self.excerpt_html = markdown(self.excerpt)#from excerpt field to excerpt_html
super(Entry, self).save(force_insert, force_update)
def get_absolute_url(self):
return "%s" % self.pub_date.strftime("year:%Y/day:%d/hour:%H/minute:%M/second:%S")
##models.permalink
#def get_absolute_url(self):
#return ('coltrane_entry_detail', (), {'year': self.pub_date.strftime("%Y"),
'month': self.pub_date.strftime("%b").lower(),
'day': self.pub_date.strftime("%d"),
'slug': self.slug})
def __unicode__(self):
return self.title
This is my entry_archive.html:
{% extends "base_entries.html"%}
{%block title%}{{block.super}} | Latest entries{% endblock %}
{% block content %}
{% for entry in latest %}
<h2>{{entry.title}}</h2>
<p>Published on {{ entry.pub_date|date:"F j P s, Y" }}</p>
{% if entry.excerpt_html%}
{{entry.excerpt_html|safe}}
{% else %}
{{entry.body_html|truncatewords_html:"50"|safe}}
{% endif%}
<p>Read full entry ...</p>
{% endfor %}
{%endblock%}
{%block whatis%}
<p>This is a list of the latest {{latest.count}} entries published in my blog.</p>
{% endblock %}
I couldn't post screenshot because i'm a new user. {{ entry.pub_date|date:"F j P s, Y" }} in my html give me correct time: December 28 11:24 a.m. 45, 2012. But {{entry.get_absolute_url}} gives me year:2012/day:28/hour:19/minute:24/seconds:45
I add the () to pub_date = models.DateTimeField(default=datetime.datetime.now()) as you guys suggested, but the result is still the same(the book actually suggests not to add () ). The thing troubles me is that {{ entry.pub_date|date:"F j P s, Y" }} gives me the correct time on my html, but {{entry.get_absolute_url}} is 8 hours ahead. I set my setting.py time zone to TIME_ZONE = 'America/Los_Angeles'. Thanks for all the quick response, but this is killing me...
change the following:
pub_date = models.DateTimeField(default=datetime.datetime.now)
to Either
pub_date = models.DateTimeField(default=datetime.datetime.now())
or
pub_date = models.DateTimeField(auto_now_add=True)
Related
I just installed django taggit by following official documentation. Every things work fine but when i click on the tags it doesn't filter post containing that tags here is my code.
Code containing models.py file
..............
from taggit.managers import TaggableManager
..................
class Post(models.Model):
STATUS_CHOICES = ((DRAFT, _('draft')),
(PUBLISHED, _('published')))
author = models.ForeignKey(get_user_model(), verbose_name=_(
"Author"), on_delete=models.CASCADE, related_name='blog_posts')
title = models.CharField(_("Title"), max_length=200, unique=True)
slug = models.SlugField(_("Slug"), unique_for_date='publish')
status = models.IntegerField(
_('status'), db_index=True,
choices=STATUS_CHOICES, default=DRAFT)
tags = TaggableManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("blog:post_detail", kwargs={
"pk": self.pk
})
code contain views.py file
from django.views.generic import ListView
class PostListView(ListView):
model = Post
queryset = Post.published.all().order_by('-publish')
context_object_name = 'post_list'
template_name = "client/pages/blog_list.html"
paginate_by = 7
urls.py file
from .views import PostListView,
..........
path('tag/<slug:tag_slug>/', PostListView.as_view(), name='post_list_by_tag'),
..........
and in the templates file
<ul class="tags-inline">
<li>Tags:</li>
{% for tag in post_detail.tags.all %}
<li>
{{ tag.name }}
,
</li>
{% endfor %}
</ul>
You need to change your queryset to filter based on the tag. This is bringing back everything based on all()
queryset = Post.published.all().order_by('-publish')
I'm not sure how you filter on Taggit
I want to display comment and it's replies in the template. But there is an issue, every reply may have some other replies. The below snippet is my Comment and CommentReply model:
class Comment(models.Model):
author = models.ForeignKey(Profile, related_name="c_sender", on_delete=models.CASCADE, unique=False)
comment = models.CharField(max_length=500, unique=False)
created_date = models.DateTimeField(auto_now_add=True)
edited_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.comment
#property
def replys(self):
return CommentReply.objects.filter(comment_id=self)
class CommentReply(models.Model):
comment_id = models.ForeignKey(Comment, related_name='sender', on_delete=models.CASCADE)
reply_id = models.ForeignKey(Comment, related_name='reply', on_delete=models.CASCADE)
Updated:
Also I have a model for WorksComments that every comments that related to Work model saved there.
class WorkComment(models.Model):
work_id = models.ForeignKey(Work, on_delete=models.CASCADE, related_name='e_exercise', unique=False)
comment_id = models.ForeignKey(Comment, related_name='e_comment', unique=False)
The below snippet is my view:
comments = WorkComment.objects.filter(work_id=work).all()
return render(request, 'work.html', {'comments': comments})
My question is how to display comments and it's replies under it, and every reply may have some other replyies that I want to display them too.
First things first... put this in your bookmarks; https://ccbv.co.uk/
You're going to want a Detail View here I suspect in order to display the details of an instance.
Setup URLs...
from django.conf.urls import url
from work.views import WorkDetailView
urlpatterns = [
url(r'^(?P<id>[-\d]+)/$', WorkDetailView.as_view(), name='work-detail'),
]
And a view;
from django.views.generic.detail import DetailView
from django.utils import timezone
from work.models import Work
class WorkDetailView(DetailView):
model = Work
def get_context_data(self, **kwargs):
context = super(WorkDetailView, self).get_context_data(**kwargs)
context['comments'] = WorkComment.objects.filter(work_id=self.object.id).all()
return context
Then a simple view might be work/work_detail.html:
<h1>{{ object.title }}</h1>
<p>{{ object.content }}</p>
<h2>Comments</h2>
{% for comment in comments %}
{{ comment }}
{% endfor %}
mysqllite table joining in django is new to me. I can query just fine on one table. and somewhat at joining via just raw mysql. What i need is an example of how to code to tables together Ie below the models and the first qustion on my project is to find all the teams that are in Atlantic confrence
I have
this in view
"atlanticsoccer": League.objects.filter(name__contains="atlantic")
this in html
<h5>Question 1</h5>
{% for whatever in atlanticsoccer %}
<li>{{whatever.name}}</li>
<li></li>
{% endfor %}
</ol>
which gives me all my Atlantic conference leauges. But i can't seem to find an example of how to join the teams by id . I have linked below the models view If i can get an example of how to do the first I can figure out the html. Thanks in advance for helping a new coder.
Models.py
from django.db import models
class League(models.Model):
name = models.CharField(max_length=50)
sport = models.CharField(max_length=15)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Team(models.Model):
location = models.CharField(max_length=50)
team_name = models.CharField(max_length=50)
league = models.ForeignKey(League, related_name="teams")
class Player(models.Model):
first_name = models.CharField(max_length=15)
last_name = models.CharField(max_length=15)
curr_team = models.ForeignKey(Team, related_name="curr_players")
all_teams = models.ManyToManyField(Team, related_name="all_players")
views.py
from django.shortcuts import render, redirect
from .models import League, Team, Player
from . import team_maker
def index(request):
context = {
"leagues": League.objects.all(),
"teams": Team.objects.all(),
"players": Player.objects.all(),
"atlanticsoccer": League.objects.filter(name__contains="atlantic")
}
return render(request, "leagues/index.html", context)
def make_data(request):
team_maker.gen_leagues(10)
team_maker.gen_teams(50)
team_maker.gen_players(200)
return redirect("index")
index.html
<h5>Question 1</h5>
{% for whatever in atlanticsoccer %}
<li>{{whatever.name}}</li>
<li></li>
{% endfor %}
</ol>
First get all teams that have a league with a name of "atlantic":
atlanticsoccer = Team.objects.filter(league__name__contains='atlantic')
Then iterate through them in your template and print whatever you want:
<ul>
{% for team in atlanticsoccer %}
<li>{{team.location}}</li>
<li>{{team.team_name}}</li>
<li>{{team.league.name}}</li>
<li>{{team.league.sport}}</li>
{% endfor %}
</ul>
Hei there,
I'm having difficulties passing two app models in one views. I have 2 apps :
Post
Author
What I expect is, I want to display Author's avatar in the Post views, so I can include it in posts loop.
Author models.py :
class Author(models.Model):
avatar = models.ImageField(upload_to='images/%Y/%m/%d', verbose_name=u'Author Avatar', validators=[validate_image], blank=True, null=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
location = models.CharField(max_length=30, blank=True)
...
Post views.py :
from app_author.models import Author
class PostList(ListView):
model = Post
template_name = 'app_blog/blog_homepage.html'
context_object_name = 'post_list'
paginate_by = 9
def get_context_data(self, **kwargs):
context = super(PostList, self).get_context_data(**kwargs)
context['post_hot'] = Post.objects.filter(misc_hot_post = True).order_by('-misc_created')[:1]
context['post_list'] = Post.objects.filter(misc_published = True).order_by('-misc_created')
context['author'] = Author.objects.all() # No need this line
return context
When I called something like this in templates, it doesn't work. The {{ author.avatar }} not showing :
{% for post in post_list %}
<ul>
<li>{{ post.title }}</li> # This is works just fine
<li>{{ author.avatar }}</li> # This does not work at all
<ul>
{% endfor %}
My Posts app urls.py :
from . import views
from django.conf import settings
from app_blog.views import PostList, PostDetailView
from django.conf.urls import include, url
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', views.PostList.as_view(), name='post-list'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Any help would be greatly appreciated!
Thank you in advance!
Regards
--- UPDATE ---
Here is my Post models.py
import datetime
from django import forms
from django.db import models
from django.conf import settings
from autoslug import AutoSlugField
from django.forms import ModelForm
from app_author.models import Author
from taggit.managers import TaggableManager
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.template.defaultfilters import slugify
# CUSTOM FILE SIZE VALIDATOR
def validate_image(fieldfile_obj):
filesize = fieldfile_obj.file.size
megabyte_limit = 5
if filesize > megabyte_limit*1024*1024:
raise ValidationError("Max file size is %sMB" % str(megabyte_limit))
class Category(models.Model):
# PRIMARY DATA
id = models.AutoField(primary_key=True)
category_name = models.CharField(max_length=200, verbose_name=u'Category Name', blank=False, null=False)
def __str__(self):
return str(self.category_name)
class Post(models.Model):
# PRIMARY DATA
post_image = models.ImageField(upload_to='images/%Y/%m/%d', verbose_name=u'Post Featured Image', validators=[validate_image], blank=True, null=True)
post_author = models.ForeignKey(Author, related_name="user_posts", null=True, blank=True)
post_title = models.CharField(max_length=200, verbose_name=u'Post Title', blank=False, null=False)
post_sub_title = models.CharField(max_length=200, verbose_name=u'Post Sub-Title', blank=False, null=False)
post_category = models.ForeignKey('Category', verbose_name=u'Post Category', on_delete=models.CASCADE)
post_content = models.TextField()
post_tags = TaggableManager()
slug = AutoSlugField(populate_from='post_title')
# MISC
misc_created = models.DateTimeField(default=datetime.datetime.now, null=True, blank=True)
misc_modified = models.DateTimeField(default=datetime.datetime.now, null=True, blank=True)
misc_hot_post = models.BooleanField(default=False)
misc_published = models.BooleanField(default=False)
def __str__(self):
return str(self.post_title)
#models.permalink
def get_absolute_url(self):
return 'app_blog:post', (self.slug,)
Thank you
--- UPDATE 2 ---
SOLVED
#Gagik & #Daniel answer sloved my problem. I just have to use this tag instead :
{{ post.post_author.avatar }}
I did not change any code above. Except I dont need this line :
context['author'] = Author.objects.all()
Thank you
You need to related Author and Post models to each other by ForeignKey file, like:
class Post (models.Model):
author = models.ForeignKey(Author)
Then when you can access to your avatar through post.author.
Updated:
Updating answer after question updated.
I think you need to update your template as follows. use post.post_author.avatar to access the avatar you need:
{% for post in post_list %}
<ul>
<li>{{ post.title }}</li> # This is works just fine
<li>{{ post.post_author.avatar }}</li> # This does not work at all
<ul>
{% endfor %}
Considering this please note that you don't need to search Author's desperately in your view. So you don't need to have following line:
context['author'] = Author.objects.all() # This is where I expect the magic is
Because when you have ForeignKey then you already have access to Author through post object.
Gagik and JF's answers should have been enough for you to work out what to do. Your foreign key is called "post_author", so that's what you should use in the template:
{{ post.post_author.avatar }}
There's no need for you get all the authors and pass them to the template in your view as you are doing.
I'm new in Django and I'm developing an app but I'm stuck in this Error.
First I want to apologize for my English since is not my first language and then I hope I'm in the right place to ask for little help.
I'm developing a website about Publication of articles. The page "Publication" return a list of the model instances - in my case all the publications in the db.
What I'm trying to do is to assign a url to each of the instances of my Model, such that the user can click on it and see the page which is populated with other relevant information of that instance.
To do this I'm using get_absolute_url in my template and DetailView in my view.
The list of all the instance works fine but when I click on each of the instance I run the error 'NoneType' object has no attribute '_default_manager' .
I google already and try to follow some guidelines here and there, and try to find solution in Django doc couldnt figure out the solution...
Here my code:
models.py
class Publications(MPTTModel):
code = models.CharField(max_length=50)
title = models.CharField(max_length=150)
date = models.DateField(null=True)
magazine = models.CharField(max_length=50)
country = models.CharField(max_length=30)
slug = models.SlugField(max_length=150)
img01 = models.ImageField(upload_to="photo", blank=True, null=True)
link = models.URLField(max_length=200, blank=True, null=True)
template = models.ForeignKey("Template", related_name="publications", null=True, blank=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
control_field = models.CharField(max_length=15)
class Meta:
verbose_name_plural = "Publications"
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse('mag-publication',args=(self.slug,))
publications.html
{% load mptt_tags %}
{% load sito_tags %}
{% full_tree_for_model myApp.Publications as publications %}
{% for publications,structure in publications|tree_info %}
{% if publications.img01 %}
<div id="title_publication_container">
{{ publications.magazine }}
</div>
{% else %}
....
{% endif %}
{% endfor %}
urls.py
urlpatterns = patterns('',
url(r'^(?P<id_page>\d+)/(?P<slug>[\w-]+)/$', pages,),
url(r'^(?P<id_page>\d+)/(?P<slug_page>[\w-]+)/(?P<id>\d+)/(?P<slug>[\w-]+)/$', projects,),
url(r'^mag-publication/(?P<slug>[\w-]+)/$', PublicationDetailView.as_view() , name='mag-publication'),
)
view.py
class PublicationView(object):
queryset = Publications.objects.all()
class PublicationListView(PublicationView, ListView):
paginate_by = 20
class PublicationDetailView(PublicationView, DetailView):
slug_field = 'slug'
The error show me this Debug informations:
AttributeError at /6/publications/*title_publication*/
**'NoneType' object has no attribute '_default_manager'**
Request Method: GET
Request URL: .../6/publications/*title_publication*/
Django Version: 1.5.4
Exception Type: AttributeError
Exception Value: 'NoneType' object has no attribute '_default_manager'
Exception Location: /home/gabriele/virtual_envs/virt2/lib/python2.7/site-packages/feincms/views/cbv/views.py in get_object, line 20
Python Executable: /home/gabriele/virtual_envs/virt2/bin/python
Maybe the problem has something to do with feincms as it said in the "Exception Location" but everything came out after I tried to work on the instance of the Model.
Thank you for your help.
You probably didn't add feincms.module.page to your INSTALLED_APPS as per the documentation. If you follow the traceback, the error appears in get_object() where it tries to access the page model.
Are you using an older FeinCMS version? Newer versions raise a warning in that case.
Well i don't know for feincms but in your views you have :
class PublicationView(object):
queryset = Publications.objects.all()
class PublicationListView(PublicationView, ListView):
paginate_by = 20
class PublicationDetailView(PublicationView, DetailView):
slug_field = 'slug'
First of all you don't need to set the slug field if his name is already 'slug'.
And an other thing :
You inherit from PublicationView in your PublicationDetailView, but the DetailView need a single object, just try like this in your url file :
url(r'^mag-publication/(?P<slug>[\w-]+)/$', DetailView.as_view(model=Publications) , name='mag-publication')
Off course don't forget to import DetailView and Publications model into your url file.
EDIT 20/08/2014
In your get_absolute_url method you use :
return reverse('mag-publication',args=({'slug':self.slug}))
If you want to use dict for params you must use :
return reverse('mag-publication',kwargs={'slug':self.slug})
And if you want to use args you must do :
return reverse('mag-publication',args=(self.slug,))
I solved part of the problem. I used a combination of get_absolute_url and DetailView.
I can see the perfectly the list of the publications in publication.html but when I click to one of them the app show me - in publications_detail.html - the detail of all the instances of the Model instead only one.
From publications in admin "view on site" it works but there's the same problem, show me all the instances together.
The question is how to catch only one instance. Follow the code :
models.py
class Publications(MPTTModel):
title = models.CharField(max_length=150)
slug = models.SlugField(max_length=150)
img01 = models.ImageField(upload_to="photo", blank=True, null=True)
template = models.ForeignKey("Template", related_name="publications", null=True, blank=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
control_field = models.CharField(max_length=15)
class Meta:
verbose_name_plural = "Publications"
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse('mag-publication',args=(self.slug,))
views.py
class PublicationsDetail(DetailView):
queryset = Publications.objects.all()
template_name = 'website/publications_detail.html'
urls.py
url(r'^mag-publication/(?P<slug>[\w-]+)/$', PublicationsDetail.as_view()
publications_detail.html
{% load mptt_tags %}
{% load sito_tags %}
{% full_tree_for_model napeApp.Publications as publications %}
{% for publications,structure in publications|tree_info %}
{% if publications.img01 %}
<div id="title_publication_container">
{{ publications.magazine }}
</div>
{% else %}
....
{% endif %}
{% endfor %}
In my case I just renamed meta to Meta and it solved.maybe it is related to sensitive capital class name