There is a view for detail:
def get_viewNum(request, numNom):
md = Nomenclature.objects.get(pk=numNom)
all_changes_for_md = Changes.objects.filter(numNomenclature_id=md.numNom)
return render(request,'Sklad/viewNum.html',context = {'nomenclature':md, 'changes':all_changes_for_md})
There is also a view to display the table:
class TableView(ListView):
model = Nomenclature
context_object_name = 'nm'
template_name = 'Sklad/viewTable.html'
In template, I output a table and I want that when the button is clicked, there is a transition to the detail of the desired nomenclature.
My template:
///
{% for item in nm %}
<tr>
<td>{{item.numNom}}</td>
<td>{{item.nameNom}}</td>
<td>{{item.quantity}}</td>
<td>{{item.numPolk}}</td>
<td>Просмотр</td>
<td><button>Печать</button></td>
</tr>
{% endfor %}
///
How do I pass the desired numNom to the url detail string?
If you use this:
...
<td>Просмотр</td>
...
Returns an error:
NoReverseMatch at /table/ Reverse for 'prosmotr' with arguments
'('',)' not found. 1 pattern(s) tried: ['news/(?P[^/]+)/\Z']
My urls.py:
urlpatterns = [
path('', home, name='rashod'),
path('add_changes/',CreateChanges.as_view(), name = 'add_changes'),
path('save', save),
path('inventriz/', inventriz, name='invent'),
path('inventriz/inventr', inventr, name='add_invent'),
path('news/<str:numNom>/',get_viewNum, name='prosmotr'),
path('table/', TableView.as_view(), name = 'viewTable')
]
As your numNom is a CharField so the view should be:
def get_viewNum(request, numNom):
md = get_object_or_404(Nomenclature, numMom=numNom)
all_changes_for_md = get_list_or_404(Changes,numNomenclature=md)
#....
And in the html url:
...
<td>Просмотр</td>
...
``
Related
Update :: Problem solved.just follow the guy below.
in my urls.py
path('', store_view, name='store'),
path('category/<str:category_name>/', category_view, name='category'),
in views.py
def store_view(request):
categories = list(Category.objects.all())
context = {
'categories': categories,
}
return render(request, 'store/store.html', context)
def category_view(request, category_name):
category = Category.objects.get(name=category_name)
context = {
'category': category,
}
return render(request, 'store/single-category-view.html', context)
in my template : store.html , that is rendered by store_view >>
{% for item in categories %}
<a href="{% url 'category' item.name %}">
{{item.name}}
</a>
{% endfor %}
Now,the problem is, in the category column in my DB, i have got one category called 'Laptop/MacBook'.when ever this name is passed to the url, it says >>
"Reverse for 'category' with arguments '('Laptop/MacBook',)' not
found. 1 pattern(s) tried: ['category/(?P<category_name>[^/]+)/$']
But when i changed the category name from Laptop/MacBook to Laptop and MacBook , it worked fine and showed no error.
But i want to keep it as it was,'Laptop/MacBook'.How can i do that??and how do you guys deal with that?
Try encoding and decoding your DB values. Assuming its Python 3:
from urllib.parse import quote, unquote
encoded = quote("Laptop/Macbook", safe="")
decoded = unquote(encoded)
print(encoded, decoded)
Output:
Laptop%2FMacbook Laptop/Macbook
With this your route should take in the right param.
from django.http import HttpResponse, request
from django.shortcuts import render
def store_view(request):
name = "Laptop/Macbook"
return render(request, './store.html', context={"name": name})
def category_view(request, category_name):
print(category_name)
return HttpResponse(b"Here we go!")
templatetags/tags.py
from urllib.parse import quote, unquote
from django import template
register = template.Library()
#register.filter(name='encode')
def encode(name):
return quote(name, safe="")
#register.filter(name='decode')
def decode(name):
return unquote(name)
Template:
{% load tags %}
<a href="{% url 'category' name|encode %}">
{{name}}
</a>
Don't forget to add in settings:
'OPTIONS': {
'libraries':{
'tags': 'templatetags.tags',
}
},
When using a "/", django thinks that you are passing more than one parameter. To fix this, replace str by path in your urls like so:
path('', store_view, name='store'),
path('category/<path:category_name>/', category_view, name='category'),
This will make django understand that the / does not mean there are two separate parameters in your url.
I am following this tutorial https://tutorial.djangogirls.org/en/extend_your_application/ but getting Templatesyntax error when trying to pass pk from html to url using path method.
With what i have read about this error this has something to do with braces and quotes but in this case i am not able to figure out the exact problem with the syntax.
This the listview.html
{% for vehicle_list_load in vehicle_list_loads %}
<tr>
<td>{{vehicle_list_load.vehicle_num}}</td>
<td>{{vehicle_list_load.Driver_name}}</td>
<td>{{vehicle_list_load.BusinessUnit}}</td>
<td>{{vehicle_list_load.CheckinTime}}</td>
<td>{{vehicle_list_load.Type}}</td>
<td>
<a href= "{% url 'vehicle_movement:checkoutview' pk = vehicle_list_load.pk %}" class = "glyphicon glyphicon-pencil" aria-hidden ="true" > Edit</a>
</td>
</tr>
{% endfor %}
this is vehicle_movements urls.py
from django.urls import path
from vehicle_movement import views
app_name = 'vehicle_movement'
urlpatterns = [
path('checkoutview/<int:pk>/',views.checkout, name = 'checkoutview'),
]
this is main urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(('vehicle_movement.urls','vehicle_movement'),namespace = 'vehicle_movement')),
]
This is the view
def listView(request):
vehicle_list_loads = list(Checkin.objects.all().filter(Type ='Loading'))
vehicle_list_unloads = list(Checkin.objects.all().filter(Type ='Unloading'))
current_time = datetime.utcnow().replace(tzinfo=utc)
diff = current_time
return render(request,'vehicle_movement/listView.html',
{'vehicle_list_loads':vehicle_list_loads,'vehicle_list_unloads':vehicle_list_unloads,'diff':diff})
on clicking on edit this view needs to open
def checkout(request,pk):
post = get_object_or_404(Checkin, pk= pk)
return render(request,'vehicle_movement/checkout.html',{'post':post})
Your urls.py seems to be setup ok, I think the reason it is not working for you is because you have extra spaces around the parameter. The correct way, in the templates, to pass arguments is like this:
{% url 'vehicle_movement:checkoutview' pk=vehicle_list_load.pk %}
I'm trying to access a url that's like
127.0.0.1:8000/posti/qNwEXBxXQdGI4KlQfoHWOA
However I can't resolve that smalluuid.
This is the error:
NoReverseMatch at /posti/ Reverse for 'detail' with arguments
'(SmallUUID('qNwEXBxXQdGI4KlQfoHWOA'),)' not found. 1 pattern(s)
tried: ['posti/(?P[0-9a-fA-F-]+)/$']
Django has issues trying to resolve it in another view that has a string like this:
from . import views
from django.conf.urls import url
app_name = 'posti'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<slug>[0-9a-fA-F-]+)/$', views.DetailView.as_view(), name='detail'),
My DetailView is this one:
class DetailView(generic.DetailView):
model = Post
template_name = 'posti/detail.html'
slug_field = 'uuid'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Post.objects.all()
I tried rewriting get_object but it didn't do anything. I don't understand if the regex is wrong or if my view has something wrong.
EDIT:
My template on index raised the error above and it had the following code:
{% if posti_list != null %}
<ul>
{% for post in posti_list %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>No posts are available.</p>
{% endif %}
I added slug_url_kwarg = 'uuid' to the DetailView class and now it works BUT now I have a
AttributeError at /posti/qNwEXBxXQdGI4KlQfoHWOA/ Generic detail view
DetailView must be called with either an object pk or a slug.
When I try to access the specific post.
I added slug_url_kwarg = 'uuid' to the DetailView class and now it works BUT now I have a
AttributeError at /posti/qNwEXBxXQdGI4KlQfoHWOA/ Generic detail view DetailView must be called with either an object pk or a slug.
slug_url_kwarg must match your url regex group name (slug in your case, which is default value for slug_url_kwarg), so you shouldn't have changed it
For details look at the piece of Django source code here - https://github.com/django/django/blob/master/django/views/generic/detail.py#L8
project/urls.py - Here, I passed in regex for primary key
from django.urls import path, re_path, include
from contextual import views
urlpatterns = [
url('admin/', admin.site.urls),
path('well_list/', include([
re_path(r'^$', views.WellList_ListView.as_view(), name='well_list'),
re_path(r'^create/', views.AddWell_CreateView.as_view(), name='create'),
re_path(r'^(?P<pk>[-\w]+)/contextual/', include('contextual.urls')),
]))
]
contextual/urls.py
app_name = 'contextual'
urlpatterns = [
re_path(r'^$', base_views.ContextualMainView.as_view(), name='main'),
re_path(r'^bha/$', base_views.BHA_UpdateView.as_view(), name='bha'),
]
views.py
class ContextualMainView(DetailView):
template_name = 'contextual_main.html'
model = models.WellInfo
class WellList_ListView(ListView):
template_name = 'well_list.html'
context_object_name = 'well_info'
model = models.WellInfo
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# get string representation of field names in list
context['fields'] = [field.name for field in models.WellInfo._meta.get_fields()]
# nested list that has all objects' all attribute values
context['well_info_values'] = [[getattr(instance, field) for field in context['fields']] for instance in context['well_info']]
# includes well instance objects & values string list for each well
context['well_info_zipped'] = zip([instance for instance in context['well_info']], context['well_info_values'])
return context
class BHA_UpdateView(UpdateView):
template_name = 'contextual_BHA.html'
model = models.WellInfo
fields = '__all__'
success_url = reverse_lazy('well_list')
well_list.html - primary key is provided in html
<tbody>
{% for well_instance, values in well_info_zipped %}
<tr>
{% for value in values %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
contextual_main.html - primary key is NOT provided in html
<button type="button" class="btn btn-default" data-container="body" data-toggle="popover">
BHA
</button>
And here is the issue:
http://127.0.0.1:8000/well_list/123412-11-33/contextual/ does not work and gives me error:
NoReverseMatch at /well_list/123412-11-33/contextual/
Reverse for 'bha' with no arguments not found. 1 pattern(s) tried: ['well_list\\/(?P<pk>[-\\w]+)/contextual/bha/$']
However, if I modify my contextual_main.html, and manually pass in a primary key, it works:
<button type="button" class="btn btn-default" data-container="body" data-toggle="popover">
BHA
</button>
It seems that I have to pass in primary key again, if I want to access http://127.0.0.1:8000/well_list/123412-11-33/contextual/bha/
Why does Django make me to pass in pk again, when I already have passed in pk in the parent url? Since I've already passed in pk in well_list.html, which is a parent page of contextual_main.html, my understanding is that I don't have to pass it again.
Is there any way to work this around, like making django to just inherit the primary key from parent, or doing it without re-injecting primary key?
url template tag does not consider current path in the context. It uses django's reverse method to create url from the given parameters.
Quoting the first line from the documentation of url templatetag.
Returns an absolute path reference (a URL without the domain name) matching a given view and optional parameters.
So in your case, you have to pass pk in the contextual_main.html to get the url in the html resolved.
Check docs for more details.
https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#url
Check docs of reverse for more details on it.
https://docs.djangoproject.com/en/2.0/ref/urlresolvers/#reverse
I'm working on extending Horizon to include a custom app.
In that app, I have a DataTable:
class WorkloadsTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Name"))
description = tables.Column("description", verbose_name=_("Description"))
image = tables.Column("image", verbose_name=_("Image"))
flavor = tables.Column("flavor", verbose_name=_("Flavor"))
class Meta:
name = "workloads_table"
verbose_name = _("Workloads Table")
table_actions = (CreateNewWorkload, DeleteWorkload)
row_actions = (UpdateWorkload, DeleteWorkload)
which has a LinkAction:
class UpdateWorkload(tables.LinkAction):
name = "update"
verbose_name = _("Edit Workload")
url = "horizon:mydashboard:workloads_panel:update"
classes = ("ajax-modal",)
icon = "pencil"
def get_link_url(self, datum):
base_url = super(UpdateWorkload, self).get_link_url(datum)
workload_id = self.table.get_object_id(datum)
reversed = urlresolvers.reverse(self.url, args=[workload_id])
print reversed
return urlresolvers.reverse(self.url, args=[workload_id])
This LinkAction points to a routce in my urls.py:
WORKLOADS = r'(?P<workload_id>[^/]+)/%s$'
urlpatterns = patterns('',
url(r'^create/$', views.CreateView.as_view(), name='create'),
url(WORKLOADS % 'update', views.UpdateView.as_view(), name='update'),
url(r'^$', views.IndexView.as_view(), name='index'),
)
The issue is: When I enter the following url:
http://localhost:9000/mydashboard/workloads_panel/3/update
I get: NoReverseMatch: Reverse for 'update' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'mydashboard/workloads_panel/(?P<workload_id>[^/]+)/update$']
Where am I going wrong?
I guess the solution to your problem lies in the _update.html where you have to include the URL as,
{% block form_action %}
{% url 'horizon:mydashboard:workloads_panel:update' workload.id %}
{% endblock %}
while the workload.id is the object's id that you get in views.py in get_context_data function:
def get_context_data(self, **kwargs):
context = super(## the class name ##, self).get_context_data(**kwargs)
try:
context['workload'] = ##your API call ##(self.request,
self.kwargs['id'])
except Exception:
exceptions.handle(self.request)
return context
May be this will help you to resolve the error.
Well now the answer is quite simple. There is no matching URL for this reverse call:
{% url 'horizon:mydashboard:workloads_panel:update' %}
The update named URL pattern requires a valid workload_id argument matching your regex [^/]+