solr and django-haystack search result nothing,,search_indexes.py? - django

every one I am trying the solr and django-haystack to make my search,,I can see there are 9 Docs in my solr,,,and in my db there are 9 data actually,,however,,when it comes to search form and search ,,I got no result ,,
I have to search designer
solr
models.py
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from django.utils import timezone
.....
class ProductsTbl(models.Model):
model_number = models.CharField(max_length=255, blank=True, unique=True,error_messages={'unique':"這 model number 已經被註冊了 ."})
name = models.CharField(max_length=255, blank=True, null=True)
material = models.CharField(max_length=255,blank=True, null=True)
color = models.CharField(max_length=255, blank=True, null=True)
feature = models.TextField(blank=True, null=True)
created = models.DateTimeField(editable=False)
modified = models.DateTimeField(auto_now=True)
release = models.DateTimeField(blank=True, null=True)
twtime = models.DateTimeField(blank=True, null=True)
hktime = models.DateTimeField(blank=True, null=True)
shtime = models.DateTimeField(blank=True, null=True)
jptime = models.DateTimeField(blank=True, null=True)
suggest = models.TextField(blank=True, null=True)
description = models.TextField(blank=True, null=True)
cataloggroup = models.ManyToManyField(CatalogGroup)
place = models.ManyToManyField(Place)
scale = models.ManyToManyField(Scale)
slug = models.SlugField(unique=True)
user = models.ForeignKey(User, blank=True, null=True)
useredit = models.CharField(max_length=32, blank=True, null=True)
image = models.ImageField(upload_to=get_imagep_Product, blank=True)
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.created = timezone.now()
return super(ProductsTbl, self).save(*args, **kwargs)
views.py
.....
from haystack.query import SearchQuerySet
.....
def post_search(request):
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(ProductsTbl).filter(content=cd['query']).load_all()
# count total results
total_results = results.count()
return render(request, 'search.html', {'form': form,
'cd': cd,
'results': results,
'total_results': total_results})
return render(request, 'search.html', {'form': form,})
settings.py
.......
INSTALLED_APPS = (
.....
'haystack',
.....
)
....
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
'URL': 'http://127.0.0.1:8983/solr/designer'
},
}
I guess probably search_indexes.py not correct
search_indexes.py
import datetime
from haystack import indexes
from .models import ProductsTbl
class ProductsTblIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
author = indexes.CharField(model_attr='user')
# created = indexes.DateTimeField(model_attr='created')
def get_model(self):
return ProductsTbl
# def index_queryset(self, using=None):
# """Used when the entire index for model is updated."""
# return self.get_model().objects.filter(created__lte=datetime.datetime.now())
search/indexes/designer/productstbl_text.txt
{{ object.title }}
{{ object.user.get_full_name }}
{{ object.body }}
search.html
{% block title %}Search{% endblock %}
{% block content %}
{% if "query" in request.GET %}
<h1>Posts containing "{{ cd.query }}"</h1>
<h3>Found {{ total_results }} result{{ total_results|pluralize }}</h3>
{% for result in results %}
{% with post=result.object %}
<h4>{{ post.title }}</h4>
{{ post.body|truncatewords:5 }}
{% endwith %}
{% empty %}
<p>There are no results for your query.</p>
{% endfor %}
<p>Search again</p>
{% else %}
<h1>Search for posts</h1>
<form action="." method="get">
{{ form.as_p }}
<input type="submit" value="Search">
</form>
{% endif %}
{% endblock %}
after I run python manage.py rebuild_index
here is my data in mysql
there are 9 data ,,just like the solr shows 9 docs,,,
however, after I run the search form ,,,it shows no result
the solr console just shows

Related

Djago time widget not showing up

All I want to do is add time widget to my form so I can easily pick the time. Everything is very simple, the page is loading but the widgets don't show up. No error nothing. I am thinking maybe I didn't set up the form widgets correctly but not sure what I did wrong. Here is my Forms.py-
from django.contrib.admin import widgets
from django.contrib.admin.widgets import AdminDateWidget, AdminTimeWidget, AdminSplitDateTime
class WorkOutForm(ModelForm):
class Meta:
model = WorkOut
fields = '__all__'
widgets={
'start':AdminTimeWidget(),
'end':AdminTimeWidget(),
}
Here is the Models.py. You will notice "start" and "end" fields are timefield-
class WorkOut(models.Model):
date=models.DateField(auto_now_add=True, auto_now=False, blank=True)
day=models.DateField(auto_now_add=True, auto_now=False, blank=True)
start=models.TimeField(null=True)
name=models.CharField(max_length=100, choices=move)
weight=models.CharField(max_length=100, blank=True)
rep=models.CharField(max_length=100, blank=True)
pedal= models.CharField(max_length=100, blank=True)
stretchtype =models.CharField(max_length=100, blank=True)
end=models.TimeField(null=True)
note=models.TextField(max_length=300, blank=True)
def __str__(self):
return self.name
And here are the views linked to it even though I don't think it has much relevance-
def workout(request):
form=WorkOutForm()
if request.method=="POST":
form=WorkOutForm(request.POST)
if form.is_valid():
form.save()
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
def update_workout(request, pk):
order=WorkOut.objects.get(id=pk)
form=WorkOutForm(instance=order)
if request.method=='POST':
form=WorkOutForm(request.POST, instance=order)
if form.is_valid():
form.save()
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
And the form on HTML page is also very basic,so don't think there is any issue there either-
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit">
</form>
What have I done wrong here? How can I make those widgets to show up?
You can try to fill the default values with the current time.
from datetime import datetime
class WorkOut(models.Model):
move = (("1", "Tom"), ("2", "Sara"), ("3", "Emilia"),)
date = models.DateField(auto_now_add=True, auto_now=False, blank=True)
day = models.DateField(auto_now_add=True, auto_now=False, blank=True)
start = models.TimeField(default=datetime.now, null=True)
name = models.CharField(max_length=100, choices=move)
weight = models.CharField(max_length=100, blank=True)
rep = models.CharField(max_length=100, blank=True)
pedal = models.CharField(max_length=100, blank=True)
stretchtype = models.CharField(max_length=100, blank=True)
end = models.TimeField(default=datetime.now,null=True)
note = models.TextField(max_length=300, blank=True)
def __str__(self):
return self.name
Update 22.10.2022
Made fields with time selection on bootstrap.
For this you need to install:
pip install django-bootstrap4
pip install django-bootstrap-datepicker-plus
In the WorkOutForm class in init set the styles for all fields.
forms.py
from bootstrap_datepicker_plus.widgets import TimePickerInput
class WorkOutForm(ModelForm):
class Meta:
model = WorkOut
fields = "__all__"
widgets = {
"start": TimePickerInput(),
"end": TimePickerInput(),
}
def __init__(self, *args, **kwargs):
super(WorkOutForm, self).__init__(*args, **kwargs)
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
"class": "form-control"
})
templates
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}
<form action="" method="POST" style="width: 20%">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>

Django Model form not saving data to the database model on form submission

I have created a project and added models in the models and also created a form in forms.py. I am trying to modify some values using the commit=False. On submitting the form, it's not saving the data to the database and there is no error thrown from the code. I have no idea on how I can solve the issue.
models.py
from django.db import models
from django.contrib.auth.models import User
class Agent(models.Model):
name = models.CharField(max_length=255)
id_no = models.CharField(max_length=20)
address = models.CharField(max_length=255)
gender = models.CharField(max_length=8)
age = models.IntegerField()
agent_no = models.CharField(unique=True, max_length=12, null=True)
email = models.EmailField(max_length=50)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.name}"
class Company(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
name = models.CharField(max_length=255, null=True, blank=True)
address = models.CharField(max_length=255, null=True, blank=True)
telephone = models.IntegerField( null=True, blank=True)
email = models.EmailField(max_length=50, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.name}"
class Task(models.Model):
company = models.ForeignKey(Company, null=True, on_delete=models.SET_NULL)
agent = models.ForeignKey(Agent, null=True, on_delete=models.SET_NULL)
cargo = models.CharField(max_length=200)
document = models.FileField(upload_to='documents/')
quantity = models.FloatField()
amount = models.FloatField()
duty = models.FloatField(null=True, blank=True)
status = models.CharField(max_length=50, default='Pending')
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.cargo}"
forms.py
from django.contrib.auth.models import User
from django import forms
import re
from django.core.exceptions import ValidationError
from .models import *
class TaskForm(forms.ModelForm):
cargo = forms.CharField( required=False)
document = forms.FileField()
quantity = forms.FloatField()
amount = forms.FloatField()
class Meta:
model = Task
fields = ['cargo', 'document', 'quantity', 'amount']
views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .forms import *
from django.contrib.auth.models import Group
from django.contrib.auth import login, authenticate
#login_required(login_url='/login/')
def task(request):
if request.method == "POST":
form=TaskForm(request.POST)
if form.is_valid():
m = form.save(commit=False)
m.status ='Pending'
m.company = request.user.username
m.save()
else:
form= TaskForm(None)
context = {'form':form}
return render(request, 'registration/templates/task.html', context)
template.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<div class="container my-2 d-flex" style="align-items:center; justify-content:center;">
<div class="card d-flex" style="width:70%; align-items:center; justify-content:center;">
<div class="form-control pt-3 " style="text-transform:uppercase;color:green"><h5>Upload trip information
</h5>
</div>
<div class="card-body" style="width:98%">
{{ form|crispy}}
</div>
<div class="card-footer" style="width:98%">
<input type="submit" value="Upload Information" class="btn btn-outline-secondary btn-sm">
</div>
</div>
</div>
</form>
{% endblock %}
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.urls import reverse
from django.http import HttpResponseRedirect
from .forms import *
from django.contrib.auth.models import Group
from django.contrib.auth import login, authenticate
#login_required(login_url='/login/')
def task(request):
if request.method == "POST":
form=TaskForm(request.POST,request.FILES) # this is important if you are dealing with files
if form.is_valid():
m = form.save(commit=False)
m.status ='Pending'
m.company = request.user.username
m.save()
return HttpResponseRedirect(reverse(' the url of where you want to redirect the user '))
else:
form= TaskForm()
context = {'form':form}
return render(request, 'registration/templates/task.html', context)
and in your templates try to add enctype in your form.
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="container my-2 d-flex" style="align-items:center; justify-content:center;">
<div class="card d-flex" style="width:70%; align-items:center; justify-content:center;">
<div class="form-control pt-3 " style="text-transform:uppercase;color:green"><h5>Upload trip information
</h5>
</div>
<div class="card-body" style="width:98%">
{{ form|crispy }}
</div>
<div class="card-footer" style="width:98%">
<input type="submit" value="Upload Information" class="btn btn-outline-secondary btn-sm">
</div>
</div>
</div>
</form>
{% endblock %}

The 'profile_picture' attribute has no file associated with it

I am trying to create access my profile but one of my models attributes (profile_picture) is empty and it's causing my profile page to crash. I have set blank=True, and it was working earlier but it has stopped working since and i can't figure out why. If I go to the django admin and manually add a profile then I can visit my profile again and everything works. I guess my question is why can't I view my profile even if the profile_pic attribute is empty? Shouldn't blank=True take care of that?
models.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
profile_picture = models.ImageField(upload_to='profile_pics', blank=True)
def __str__(self):
return self.user.username
views.py
def edit_user_profile(request):
if request.method == 'POST':
form = EditUserProfileForm(request.POST, instance=request.user.userprofile)
if form.is_valid():
form.save()
return redirect('/accounts/profile')
else:
form = EditUserProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/edit_user_profile.html', args)
Profile.html
<div class="container">
<br>
<h2>{{ user }}</h2>
<br>
<p>Name: {{ user.first_name }} {{ user.last_name }}</p>
<img src="{{ user.userprofile.profile_picture.url }}" width="240px">
<p></p>
<p>Motto: {{ user.userprofile.description }}</p>
<p>Youtube: {{ user.userprofile.website }}</p>
<p>About Me: {{ user.userprofile.city }}</p>
<p>Phone Number: {{ user.userprofile.phone }}</p>
Edit Profile<br>
<!-- if profile is updated succesfully -->
{% if messages %}
{% for message in messages %}
<br><br>{{ message }}
{% endfor %}
{% endif %}
</div>
Again, if I go the Django admin and manually upload a photo I can access my profile but by default it won't work without an image.
Any insight is appreciated
Thanks
It's because of the code {{ user.userprofile.profile_picture.url }} in template.
It always try to find picture's url even if your profile_picture is none.
Just add if/else in template, or add method if you have default image.
ie. if/else in template
{% if user.userprofile.profile_picture %}
<img src="{{ user.userprofile.profile_picture.url }}" width="240px">
{% else %}
<img src="{% static 'your_default_img_path' %}" width="240px">
{% endif %}
Or use method for picture
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
profile_picture = models.ImageField(upload_to='profile_pics', blank=True)
def __str__(self):
return self.user.username
def get_profile_picture(self):
if self.profile_picture
return profile_picture_url
else:
return 'your_default_img_url_path'
Try this code in views.py
form = EditUserProfileForm(request.POST, request.FILES)
if form.is_valid():
city = form.cleaned_data['city']
description = form.cleaned_data['description']
profile_picture = form.cleaned_data['profile_picture']
website = form.cleaned_data['website']
phone = form.cleaned_data['phone']
EditUser= UserProfile(city =city,
description=description,
profile_picture =profile_picture,
website =website,
phone =phone,
user_id=request.user)
EditUser.save()
return redirect('/accounts/profile')
else:
form = EditUserProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/edit_user_profile.html', args)

Reverse Iterating over Foreign Key

I am trying the tutorial for Django on making a local library website with books.
One of the challenges is to make an author detail view which lists all the books that author has written. I am having trouble displaying any book information for the author.
Model.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.urls import reverse
import uuid
# Create your models here.
class Genre(models.Model):
"""
Model resprenting the book genre
"""
name=models.CharField(max_length=200, help_text="Enter a book genre")
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(max_length=1000, help_text="Enter a brief description")
isbn = models.CharField('ISBN', max_length=13, help_text="13 character ISBN field")
genre = models.ManyToManyField(Genre, help_text="Select a genre for this book")
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book-detail', args=[str(self.id)])
def display_genre(self):
return ', '.join([genre.name for genre in self.genre.all()[:3] ])
display_genre.short_description = 'Genre'
class BookInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text="Unique book number")
book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
imprint = models.CharField(max_length=200)
due_back = models.DateField(null=True, blank=True)
LOAN_STATUS = (
('d', 'Maintenance'),
('o', 'On loan'),
('a', 'Available'),
('r', 'Reserved'),
)
status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True, default='d', help_text="Book Availability")
class Meta:
ordering = ['due_back']
def __str__(self):
return ('%s (%s)' %(self.id, self.book.title))
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.CharField(max_length=10, null=True, blank=True)
date_of_death = models.CharField(max_length=10, null=True, blank=True)
def get_absolute_url(self):
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
return ('%s, %s' % (self.last_name, self.first_name))
def display_books(self):
books = Book.objects.get(pk=self.id)
return books.book_set.all()
display_books.short_description = 'Books'
author_detail.html
Really lost here!
{% extends "base.html" %}
{% block content %}
<h1>Author: {{ author }}</h1>
<p><strong>Date of Birth:</strong> {{ author.date_of_birth }}</p>
<p><strong>Date of Death:</strong> {{ author.date_of_death }}</p>
<!--<p><strong>Books:</strong> {% for books in book.author.pk.all %} {{ book.author }}{% if not forloop.last %}, {% endif %}{% endfor %}</p> -->
<div style="margin-left:20px;margin-top:20px">
<h4>Books</h4>
{% for books in book.all %}
<p>{{ books }} Testing Vars {{ book.author_set }} Get copies from key {{ book.author.pk }} </p>
{% endfor %}
</div>
{% endblock %}
Views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.views import generic
# Create your views here.
from .models import Book, Author, BookInstance, Genre
def index(request):
num_books=Book.objects.all().count()
num_instances=BookInstance.objects.all().count()
#available books
num_instances_available=BookInstance.objects.filter(status__exact='a').count()
num_authors=Author.objects.count()
return render(request,
'index.html',
context={'num_books': num_books, 'num_instances': num_instances,
'num_instances_available' : num_instances_available, 'num_authors': num_authors},
)
class BookListView(generic.ListView):
model = Book
class BookDetailView(generic.DetailView):
model = Book
class AuthorListView(generic.ListView):
model = Author
class AuthorDetailView(generic.DetailView):
model = Author
Assuming author_detail.html is used in AuthorDetailView ListView, I'd suggest some changes in your template, maybe like this,
{% block content %}
<h1>Author: {{ object.first_name }} {{ object.last_name }}</h1>
<p><strong>Date of Birth:</strong> {{ object.date_of_birth }}</p>
<p><strong>Date of Death:</strong> {{ object.date_of_death }}</p>
<div style="margin-left:20px;margin-top:20px">
<h4>Books</h4>
{% for book in object.book_set.all %}
<p>{{ book.title }}</p>
{% endfor %}
</div>
{% endblock %}
Since, you haven't overridden the get_context_data() method of the ListView, the default context_variable_name would be object. You may need to refer the Author instance by object.

How to add categories at my django blog

I developed a django blog application using djangogirls.com tutorial. I am trying to add a blog category but I just can't do it!
I was searching google and stackoverflow.com like crazy , but , being a newbie in python/django I couldn't successfully add categories to my blog.
My models:
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
My views:
from django.shortcuts import render, get_object_or_404
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})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
My urls:
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
url(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),
]
My post_list.html:
{% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1>{{post.title }}</h1>
<p>{{ post.text|truncatewords:100}}</p>
</div>
{% endfor %}
{% endblock %}
My post_detail.html:
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endblock %}
Ok. If somebody can help me out , I need to create a category model for this blog model ,I would really appreciate it !
Thanks in advance!
I'd go with
class Category(models.Model):
title = models.CharField(max_length=255, verbose_name="Title")
...
class Post(models.Model):
category = models.ForeignKey(Category, verbose_name="Category")
title = models.CharField(max_length=255, verbose_name="Title")
text = models.TextField()
...
When you have a post like this:
post = Post.objects.first()
you can access it's category's title with post.category.title or when you have a category like this:
category = Category.objects.first()
you can get the posts under that category with category.post_set.all().
I have edited your code to show how I'd write if that was a project I am working on. Here it is:
models.py
from django.db import models
from django.utils import timezone
class Category(models.Model):
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
title = models.CharField(max_length=255, verbose_name="Title")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['title']
def __str__(self):
return self.title
class Post(models.Model):
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
is_published = models.BooleanField(default=False, verbose_name="Is published?")
published_at = models.DateTimeField(null=True, blank=True, editable=False, verbose_name="Published at")
category = models.ForeignKey(Category, verbose_name="Category")
author = models.ForeignKey('auth.User', verbose_name="Author")
title = models.CharField(max_length=200, verbose_name="Title")
text = models.TextField(verbose_name="Text")
class Meta:
verbose_name = "Post"
verbose_name_plural = "Posts"
ordering = ['-created_at']
def publish(self):
self.is_published = True
self.published_at = timezone.now()
self.save()
def __str__(self):
return self.title
views.py
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Category, Post
def category_list(request):
categories = Category.objects.all() # this will get all categories, you can do some filtering if you need (e.g. excluding categories without posts in it)
return render (request, 'blog/category_list.html', {'categories': categories}) # blog/category_list.html should be the template that categories are listed.
def category_detail(request, pk):
category = get_object_or_404(Category, pk=pk)
return render(request, 'blog/category_detail.html', {'category': category}) # in this template, you will have access to category and posts under that category by (category.post_set).
def post_list(request):
posts = Post.objects.filter(published_at__lte=timezone.now()).order_by('published_at')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
urls.py
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^category$', views.category_list, name='category_list'),
url(r'^category/(?P<pk>\d+)/$', views.category_detail, name='category_detail'),
url(r'^$', views.post_list, name='post_list'),
url(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),
]
I didn't write templates, they are up to you.
Actually this method (publish) is needed just for Django Girls tutorial, to play in shell https://tutorial.djangogirls.org/en/django_orm/
def publish(self):
self.is_published = True
self.published_at = timezone.now()
self.save()
As actions are managed by django admin, i would change
published_at = models.DateTimeField(null=True, blank=True, editable=False, verbose_name="Published at")
To
published_at = models.DateTimeField(null=True, blank=True, editable=True, default=timezone.now, verbose_name="Published at")
So when adding new post, it would set default time and you would be able to change it to whatever suits you.