Django - Multiple <pk> in urls.py with DetailViews - python

I'm trying to build a script using Django Generic display views.
My urls.py
url(r'^page/(?P<pk>[0-9]+)/$', PageDetails.as_view(), name='page-details'),
My views.py
class PageDetails(DetailView):
model = Pages
def get_context_data(self, **kwargs):
context = super(PageDetails, self).get_context_data(**kwargs)
return context
The problem
How can I set multi <pk> in my urls like this?
url(r'^page/(?P<pk>[0-9]+)/subpage/(?P<pk>[0-9]+)$', PageDetails.as_view(), name='page-details'),
In my views I need to take data from first and second <pk>.

Change the second pk argument in your url to something else, for example pk_alt:
^page/(?P<pk>[0-9]+)/subpage/(?P<pk_alt>[0-9]+)$
The url parameter pk_alt will then be available in your views function as part of the self.kwargs dictionary, so you can access it using:
self.kwargs.get('pk_alt', '')
You could then update your views to something like the following:
class PageDetails(DetailView):
model = Pages
def get_context_data(self, **kwargs):
context = super(PageDetails, self).get_context_data(**kwargs)
page_alt = Pages.objects.get(id=self.kwargs.get('pk_alt', ''))
context['page_alt'] = page_alt
return context
You will then be able to access the alternative model in your template using {{ page_alt }}

If you need two arguments in the url try this:
url(r'^page/(?P<pk_1>[0-9]+)/subpage/(?P<pk_2>[0-9]+)$', PageDetails.as_view(), name='page-details'),
Then you have pk_1 and pk_2 available as kwargs

Related

Passing a model's string parameter to URL with TemplateView

I am listing data from a search result matching the name parameter of my Model. For each result I have a link to the detail page with the key parameter (which is a string) passed in the url, Like this
<ul>
{% for x in results %}
<li><a href = 'login/index/{{x.key}}'>{{x.name}}</a></li>
{% endfor %}
</ul>
My url.py looks like this
app_name = 'kpi'
urlpatterns = [
path('login/index/search', views.SearchView.as_view(), name="search"),
path('login/index/<slug:key>', views.EpicDetailView.as_view(), name="detail")
]
And my views.py look like this:
class SearchView(LoginRequiredMixin, TemplateView):
template_name = 'KPI/search.html'
def get(self, request, *args, **kwargs):
self.q = request.GET.get('q','')
self.results = Epic.objects.filter(name__icontains= self.q)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(SearchView, self).get_context_data(**kwargs)
context['results'] = self.results
return context
class EpicDetailView(LoginRequiredMixin, TemplateView):
template_name = 'KPI/epic_detail.html'
def get_context_data(self, **kwargs):
context = super(EpicDetailView, self).get_context_data(**kwargs)
context['lone_epic2'] = Epic.objects.get(key=self.kwargs['key'])
I know I am missing a step here, probably how i created the url path, or needing logic in my views. With the code above i get a page not found error because the template view link doesn't recoginze/match the EpicDetailView url
What I'm Trying to Accomplish
The purpose is to be able to click on the search result, push the key to the url, and store that key value as a variable to use in the EpicDetailView page
NOTE: Although I'm not showing it in the code above, my detail view will be displaying data from multiple model querysets so that is why i'm using TemplateView instead of DetailView for my EpicDetailView
You should pass the slug into your URL like so in your template:
<li>{{x.name}}</li>
Make sure that kpi is properly registered as the namespace for your KPI app. More info on the URL dispatcher here: https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#url

How to retrieve data from an existing db file and display it on webpage using Django?

This is the views.py file:
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import Report
import random
class HomePageView(TemplateView):
def get(self, request, **kwargs):
args = {}
data = Report.objects.all()
args['data'] = data
return render(request, 'index.html',args)
I'm finding it difficult to understand the framework since I'm a beginner. So please help me.
You are trying to use class base view which will be different from function base view, to pass context data to template in class base view you need to override get_context_data method as below:
class HomePageView(TemplateView):
""" Home page view """
template_name = "index.html"
def get_context_data(self, **kwargs):
# first of all calling it's parent class method to get context (if any)
context = super(HomePageView, self).get_context_data(**kwargs)
# now you can update context dictionary as below:
context['data'] = Report.objects.all()
return context
Now you can access data in your template using {{ data }}
You can display the FileField content by passing the following
{{ context_obj.file_field_name.url }} in the template.

Passing 2 variables through django url

I try to pass 2 variables through url config
url.py
url(r'^essays/(?P<category>[-\w]+)/(?P<slug>[-\w]+)/$', views.EssayDetailView.as_view(), name='essay_view'),
view.py
class EssayDetailView(DetailView):
model = Essay
def get_context_data(self, **kwargs):
context = super(EssayDetailView, self).get_context_data(**kwargs)
context['category'] = Category.objects.get(slug=self.kwargs['category'])
return context
but if I use in template url tag like this
{{essay.title}}
I've error NoReverseMatch. With 1 parameter it works right. For example url:
url(r'^(?P<slug>[-\w]+)/$', views.ArticleDetailView.as_view(), name='article_view'),
how can i pass 2 variables to generic view? Or should I wright my own view method?
It was mistyping in
def get_absolute_url(self):
return reverse('articles:essay_view', args=[self.category.slug, self.slug])
now works tnx

Django - Pass URL "name" attribute to view

I've the following URL that i created:
urls.py
url(r'^authors', GenericView.as_view(model=Author, context_object_name='authors_list',
success_url=reverse_lazy('author_link'),
template_name='app/authors.html'), name='author_url_name'),
And i want to have access to the URL's name on the view, passed in a variable. In this case, 'author_url_name'.
The view function where i need it, is the following:
views.py
def get_context_data(self, **kwargs):
context = super(AuthorClass, self).get_context_data(**kwargs)
context['action'] = reverse_lazy('author_url_name')
return context
This works, but i want to replace the 'author_url_name' for some method that gives me exactly that.
Thanks for your time!!
https://stackoverflow.com/a/17614086/183948 has your answer for you.
As of Django 1.5, this can be accessed from the request object
current_url = request.resolver_match.url_name
https://docs.djangoproject.com/en/1.5/ref/request-response/#django.http.HttpRequest.resolver_matc

django haystack - how to use with current view having some context

I have a view that puts some context and renders the template from this context. I want view display all the things if no search query is there, and show searhed things, if anything searched.
class MyCurrentView(View):
def get(self, request):
data = { 'users': User.objects.all() }
return render_to_response("mytemp.html", ..
urls.py:
url(r'^search/$', MyCurrentView.as_view())
Now, I am integrating this with SEarchView like this:
class MyCurrentView(SearchView): (If u observe, I subclassed SEarchView).
template = 'mytemp.html'
def get(self, request):
data = { 'users': User.objects.all() }
return render_to_response...
def get_context_data(self, ...):
print "....this should print" #But not printing. So, unable to add data
return data
urls.py:
url(r'^search/$', MyCurrentView.as_view())
# as_view() gave me error, so I did MyCurrentView() , may be thats y, get_context_data not calling.
Will provide more information if necessary.
New Django-style class based views were added via PR #1130 to django-haystack:
https://github.com/toastdriven/django-haystack/pull/1130
You can now use search views like you normally would with django (see changes in pull request).
from haystack.generic_views import SearchView
class MySearchView(SearchView):
def get_context_data(self, **kwargs):
# do whatever you want to context

Categories