I'm having trouble figuring out how to create links on a blog I'm making. I want my index page to have links to blog posts grouped by year/month.
Here is my view that will display the all the blog posts by month/year (the url will look like 2014/10 if I want to see the blog entries from October 2014):
def month(request, year, month):
month_entry_list = Entry.objects.filter(pub_date__year=year, pub_date__month=month)
return render(request, 'blog/list_post_by_month.html', {
'month_entry_list': month_entry_list
})
Here is my index view:
def index(request):
# latest_entry_list = Entry.objects.order_by('-pub_date')[:5]
entries = Entry.objects.all().order_by('-pub_date')
latest_entry_list = entries[:5]
template = loader.get_template('blog/index.html')
context = RequestContext(request, {
'latest_entry_list': latest_entry_list
})
return HttpResponse(template.render(context))
I have an idea of how to go about this but I'm not sure it's optimal. Should I just query the database to get a list of all the year/month combinations, and use that to create links in the index template?
Maybe you could keep the relevant month-years in server-side cache (https://docs.djangoproject.com/en/dev/topics/cache/) and just update it occasionally by appending to it (i.e. just checking for more posts since the last month that had one.)
Related
I am new to Django and I have develop form with Country and State field from the Profile Model. If I search for country and a particular state, I want a list of persons belonging to that country and state to display and paginated. And if the records are in multiple pages then I should be able to click on individual pages that follow to view the searched results on those pages without losing the search results.
Here is my views code with pagination.
def search_applicants(request):
form = ApplicantsSearchForm(request.GET or None)
if form.is_valid():
list_submited = Profile.objects.filter(
nation__icontains=form.cleaned_data['nation'],
state__icontains=form.cleaned_data['state']
)
else:
list_submited = submited_apps.objects.all()
paginator = Paginator(list_submited, 5)
page = request.GET.get('page')
paged_listApps = paginator.get_page(page)
context = {
'list_applicants':paged_listApps,
'form':form,
}
return render(request, 'user/list_applicants.html',context)
I have got the pagination of all records from the Profile Model but any time I perform a search and try to click on the pagination tabs the search result is get scattered and returns to all the list items in the database.
On the front-end you need to submit your search data when clicking on your pagination tabs as well.
I'm having a bad time figuring this out through searching different stackoverflow question but I'm using a function based view to make my day simplier. But when i'm retrieving this single data from a database and showing only one record using slice. It throws beside it a tag which commonly see when we test print in our terminals. But how exactly to get rid of this?
tutorials = Tutorial.objects.values_list('id', flat=True)
courses = Course.objects.all()
tutorial_title = Tutorial.objects.filter(id__in=tutorials).values('title').values_list('title', flat=True)
context = {'tutorial': tutorials,'courses': courses, 'tutorial_title': tutorial_title}
Here's my code snippet, where when i call {{ tutorial_title | slice:'1'}}. It should only call one latest record, which works flawlessly but there is a <QuerySet tag beside the shown data.
Why not just pass it to the template as a signle title:
courses = Course.objects.all()
tutorial_titles = ', '.join(Tutorial.objects.values_list('title', flat=True))
context = {
'courses': courses,
'tutorial_titles': tutorial_titles
}
Here tutorial_titles is a comma seperated string of tutorial titles.
Or if you only want the first title:
courses = Course.objects.all()
tutorial_title = Tutorial.objects.values_list('title', flat=True).first()
context = {
'courses': courses,
'tutorial_title': tutorial_title
}
I think i just discover the answer by an accident. So i know the QuerySet is a List so in my views.py, I think i could just set a for loop on the Query itself and throw it to a empty List that will throw to the template using the context. lmao
tutorials = Tutorial.objects.values('id')
courses = Course.objects.all()
**tutorial_titleList = []**
tutorial_title = Tutorial.objects.filter(id__in=tutorials).values('title').values_list('title', flat=True)
**for tutorial in tutorial_title:
tutorial_titleList.append(tutorial)**
context = {'tutorial': tutorials,'courses': courses, 'tutorial_title': tutorial_titleList}
and in my template tag. Since it still returns a List, i just put | join: "" template tag beside
I have a django app in which I am counting the clicked urls. I am saving the clicked urls in a list in my view. Now I want to iterate through the list and count each occurence (of the urls). Then I want to show each url with the counted number in the template. What I am doing so far looks like this:
My view:
class AnalyticsIndexView(StaffRequiredMixin, ListView):
template_name = 'analytics_list.html'
model = UrlTime
def get_context_data(self, **kwargs):
context = super(AnalyticsIndexView, self).get_context_data(**kwargs)
context['url_views_list'] = UrlTime.objects.all()
context['total_views'] = UrlTime.objects.all().count
context['home_view'] = UrlTime.objects.filter(associated_url='/').count()
context['job_list'] = UrlTime.objects.filter(associated_url='/jobs/').count()
context['job_detail'] = UrlTime.objects.filter(associated_url='/jobs/{How to pass id??}').count()
context['job_'] = UrlTime.objects.filter(associated_url='/jobs/{???id?????}').count()
return context
Now that works. But I don't want to hardcode the links obviously, also because I don't know which urls will be in it. (that handles my custom middleware). I would like to capture each url in the list, count it, and show link and linkcount in the template. I already tried with Collections but it didn't work as I wanted it. Also with the harcoding I don't know how to do that with links that have a dynamic id....
Anyone has any suggestions? Help is very much appreciated. Thanks!
You need to do a GroupBy and Count aggregation. Try overriding get_query_set method with the following query:
def get_queryset():
return UrlTime.objects.values('associated_url').annotate(
url_count=Count('associated_url')
)
Here is my simple view:
def transaction_list(request):
current_user = request.user
month = datetime.date.today().month
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1
objects = Transaction.objects.filter(user=current_user, date__month=month)
p = Paginator(objects, 10, request=request)
transactions = p.page(page)
return render(request, 'transaction/list.html',
{'transactions': transactions})
It shows a list of transactions which occured in the current month.
I want to add an option to change the month of the transactions being displayed but I have no clue how to tackle this and make it work. Should it be done in a view? maybe template? I would appreciate any ideas
Take some time to read some Django docs as they may prove really valuable (not to mention they are very clean and well written for every version available). I would focus on Working With Forms
In short, you'll pass the month from your django template (maybe via ajax or a simple HTML form POST), to your view, and use your view function to get the POST data and use that in your queryset.
It is hard to provide a good, thorough answer because there are different ways to do this. Do you want AJAX? Simple form with page reload, etc?
Okay, here, in detail, is how I usually handle a POST request. This isn't tested code, it's just psuedo code, but should work as far as I can tell, aside from a few minor typos probably. BUT, it should give you an idea of how to handle ajax requests in Django.
This is pretty 101 and taking some time to read the docs and run through some of the early projects covers a these concepts much I, so my going into more depth isn't really valuable to SO readers.
views.py
class change_date_form(forms.Form):
new_date = forms.DateField()
def change_transaction_date(request):
#Do some checks to make sure user is authorized to do this
current_user = ...
customer_data = []
if request.method == 'POST':
form = change_date_form(request.POST, request.FILES)
if form.is_valid():
change_date = form.cleaned_data.get('new_date')
objects = Transaction.objects.filter(user=current_user, date__month=change_date)
for i in objects:
customer_data.append(objects.name)
response_data = json.dumps(customer_data)
return HttpResponse(response_data, content_type='application/json')
urls.py
...
url(r'^change_date_view/', 'module.views.change_transaction_date'),
Jquery:
$('button_handler').on('click', function() {
var new_date_value = $(date_field_selector).val()
$.ajax({
url: "/change_date_view/",
type: "POST",
data: {
new_date: button_handler,
},
success:function(data) {
//build your html via javascript with response data
}
})
})
I am on my first project with the Django framework, and I decided to create a blog, since it is easy to find stuff about it online. I, then, found out about the Paginator module, and decided to use it. The problem is, whenever I add a post it goes to the end of the Database, so I have a blog that, so far, displays old posts first.
Because of that, I decided to use .reverse(), like this:
def index(request):
posts = Post.objects.all()
posts.reverse()
paginator = Paginator(posts, 2)
try:
page = int(request.GET.get("page", "1"))
except ValueError:
page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = paginator.page(paginator.num_pages)
return render_to_response('index.html', {
'Posts': posts,
'Sideposts': Sidepost.objects.all(),
})
The only problem is, this doesn't work, at least not with Paginator. When I stop using Paginator it works, but otherwise it doesn't.
I think this is a really weird behaviour, and I had a look around but couldn't find anything that helped me with this problem. Am I doing anything wrong?
Let the database do the ordering:
posts = Post.objects.all().order_by('-id')
Of course, it would be better to use a date field or something.
First, Post.objects.all() does not return a list object, but queryset object.
And reverse method does not change the queryset itself, but returns reversed version of queryset.
Convert it to list posts = list(Post.objects.all()) to use reverse method if you want list object.
Maybe following is more preferable:
posts = Post.objects.all().reverse()