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 [^/]+
Related
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>
...
``
My webapp was working fine, but after doing some ldap configurations (only changes regarding ldap in settings.py) my routing to certain pages seemed to brake. My urls.py seems to be in order but when i go to the view page i want to see it gives me another template.html file.
my urls.py
appname = 'app'
urlpatterns = [
path('logout/', views.LogOutView.as_view(), name='logout'),
path('', views.LoginView.as_view(), name='login'),
path('index/search', views.SearchView.as_view(), name="search"),
path('index/<slug:key>', views.EpicView.as_view(), name="detail"),
**path('index/exec_report', views.ExecView.as_view(), name = "exec"),
**path('index/exec_version_report', views.ExecVersionView.as_view(), name = "version"),
path('index/', views.IndexView.as_view()),
]
Now all the paths work well, but the 2 with ** next to them are the ones returning with the EpicView template
So in my index.html is where you click on a search to bring you to index/exec_version_report
index.html
<form method="GET" action = "{% url 'app:version' %}">
<select name ="versionA" >
<option value = 0>0</option>
</select>
<select name = "versionB">
<option value = 4.2> 4.2</option>
<option value = 4> 4.0</option>
</select>
<input type="submit" value="Search"/>
</form>
Now the url routing is correct when i click on "Search" but it is giving me the wrong template, but you can see that the template_name is not resolving to the one i had given it:
class ExecVersionView(LoginRequiredMixin, TemplateView):
template_name= 'APP/exec.html'
def get(self, request, *args, **kwargs):
self.versionA = request.GET.get('versionA','')
self.versionB = request.GET.get('versionB','')
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
versionBint = Version(self.versionB)
versionAint = Version(self.versionA)
context = super(ExecVersionView, self).get_context_data(**kwargs)
open_low = ExecVersion.objects.filter(version__gte= versionAint, version__lte=versionBint, severity = 'Low', status='Open')
context['open_low'] = open_low
return context
Now for some reason this view will give me the wrong template file, And this is doing it to both of those ** routes/views
I am 100% certain that this is the correct .html file location
"index/exec_report" matches the path "index/<slug:key>" and Django returns the first path that matches. So it returns the detail view with key="exec_report".
Just move your detail path with the slug to a position after the two paths that don't work.
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
I'm trying to display a list of links to a list view in Django but I keep getting a "NoReverse Match" error.
Template
{% for posts in all_posts %}
{{posts.title}}
{% endfor %}
Views
from blog.models import Posts
from main_site.views import LayoutView
class BlogView(LayoutView, generic.ListView):
template_name = 'blog/blog.html'
model = Posts
context_object_name = 'all_posts'
Blog / urls
urlpatterns = patterns('',
url(r'^(?P<slug>\w+)/$', views.SingleView.as_view(), name='blog_single'),
url(r'^$', views.BlogView.as_view(), name='blog_home'),
)
Project /urls
urlpatterns = patterns('',
url(r'^blog/', include('blog.urls', namespace='blog')),
)
slug is property in my model set to models.SlugField() and if I output as just {{posts.slug}} it shows up so I know it's not empty. I have a similar link set up in a different app in the project that's working fine (exact same set up -- url 'namespace:name') so I'm not sure what's causing this to break.
The full error is:
NoReverseMatch at /blog/
Reverse for 'blog_single' with arguments '(u'test-slug',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'blog/(?P<slug>\\w+)/$']
this is because you have bad url pattern.
url(r'^(?P<slug>\w+)/$', views.SingleView.as_view(), name='blog_single'),
is expecting \w+ (that is any letter character, number character or underscore). But you are supplying it with a text containing a dash ("-").
So you need change your slug or url pattern to be like:
url(r'^(?P<slug>[\w-]+)/$', views.SingleView.as_view(), name='blog_single'),
I am trying to make pretty meaningful urls, but I guess I'm doing it wrong.
This works:
from django.conf.urls.defaults import patterns, url
from places.views import explore_view
urlpatterns = patterns('',
url(r'', explore_view, name='explore'),
)
This does not:
from django.conf.urls.defaults import patterns, url
from places.views import explore_view
urlpatterns = patterns('',
url(r'(?P<countryorcategory>[0-9A-Za-z._%+-]+)', explore_view, name='explore'),
)
As I get this error:
Reverse for 'explore' with arguments '()' and keyword arguments '{}'
not found.
Here is the code for explore_view:
def explore_view(request, countryorcategory=None):
"""
This is the explore view - to view places sugeested by ambassadors
"""
user = request.user
page = request.GET.get("page", 1)
per_page = request.GET.get("per_page", 20)
category_id = request.GET.get("category_id", None)
attrs = request.GET
lat = safe_attr(attrs, "lat", "float", None)
lon = safe_attr(attrs, "lon", "float", None)
q = request.GET.get('q', None)
if q and not lat or lon:
cache_key = 'GoogleGeocode-{}'.format(hashlib.md5(q.encode('UTF-8', 'replace')).hexdigest())
latlon = cache.get(cache_key)
if not latlon:
latlon = geocode(q)
if latlon:
cache.set(cache_key, latlon)
if latlon:
lat = latlon['lat']
lon = latlon['lng']
if not q:
q = ''
category_names = getattr(settings, "EXPLORE_CATEGORIES", [])
categories = [Category.objects.get(name=cat_name).serialize() for cat_name in category_names]
more = True
places = Place.objects.explore_places(user, category_id=category_id, lat=lat, lon=lon, page=page, per_page=20)
if len(places) != per_page:
more = False
return render_to_response('explore/main.html', {'places': places, 'categories': categories, 'category_id': category_id, 'lat': lat, 'lon': lon, 'more': more, 'q': q}, RequestContext(request))
This line:
url(r'(?P<countryorcategory>[0-9A-Za-z._%+-]+)', explore_view, name='explore')
...is defining an url that takes an argument countryorcategory in the template. You need to put an argument on your url either of the following in your template:
{% url 'explore' argument %}
{% url 'explore' countryorcategory=argument %}
If you want to continue to use non-argument urls with the same name, you can define additional urls with the same name but with different patterns. For example:
urlpatterns = patterns('',
url(r'(?P<countryorcategory>[0-9A-Za-z._%+-]+)', explore_view, name='explore'),
url(r'', explore_view, name='explore'),
)
Then {% url 'explore' %} should work both with and without an argument.
For me, I forgot the namespace of the Route. Instead of
{% url 'login' %}
I should have written
{% url 'accounts:login' %}
with this configuration:
# root URLs
url(r'^accounts/', include('myproject.accounts.accounts.urls', namespace='accounts'))
# accounts URLs
url(r'^login$', views.login, name='login')
I'm assuming you are using a template with something like this :
{% url 'explore' argument %}
And this error probably means that the argument is not set to anything.