Passing 2 variables through django url - python

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

Related

Overriding get_context_data() is not working in child view

I am trying to override get_context_data() in a child class-based view to send more contextual data to the template, but it doesn't work. As a sample I am sending a test variable, but it is not rendered in the template.
class ProductList(LoginRequiredMixin, View):
template_name = 'product/product_scroll.html'
def get(self, request, *args, **kwargs):
#...
return render(request, self.template_name, data)
class Feed(ProductList):
template_name = "product/feed.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['test'] = 'sometestinfo'
return context
But in the template:
<p> Prueba: {{test}} </p>
is empty.
It's not working because you override get. Therefore the whole built in functionality of the view - including calling get_context_data - is bypassed. You almost never need to define the get or post methods.

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

return to specific page in Django

I would like to return to a specific page after I edit a record using Django "UpdateView", however this page url needs an argument passed to it as well (see urls.py below). I am pretty sure I need to use "get_absolute_url", which works when I am just redirecting to an unfiltered page, but can't seem to get the syntax to redirect to a filtered page.
Models.py
class DefaultDMLSProcessParams(models.Model):
device = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,)
customerTag = models.CharField(max_length=50,)
processNotes = models.TextField(max_length=300,blank=True,default = "")
def __str__(self):
return str(self.defaultParamDescrip)
def get_absolute_url(self):
#self.object.pk? pass this below somehow?
return reverse('Default_Listview',)
views.py
class defaultUpdateView(LoginRequiredMixin,UpdateView):
model = models.DefaultDMLSProcessParams
fields = ['processNotes','customerTag']
template_name = 'default_edit.html'
login_url = 'login'
urls.py
path('<int:device>', DefaultsListView.as_view(), name='Default_Listview'),
Specify the parameter by args argument of reverse() function
def get_absolute_url(self):
# self.object.pk? pass this below somehow?
return reverse('Default_Listview', args=[self.id, ])
You could find more example in the Official Django doc .

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

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

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

Categories