urlpatterns don't get updated after DB insertion? - python

I'm having an html form which inserts data into one table called srv.
I've built the urls.py in such a way to capture every insertion:
for item in srv.objects.all():
linkSrv = item.loc.lower() + '/srv/' + item.subctg.lower() + '/' + item.title.lower()
urlpatterns += patterns('',
url(r'^' + linkSrv + '/$', 'beta.views.queryFromIndexDeep'),
)
After the one insertion is being made, e.g. loc='loc', subctg='subctg' and title='title'
if i point my browser to 127.0.0.1:8000/loc/srv/subctg/title/ i get the http404 error (no matching url)
If I 'force-save' the urls.py (vim urls.py then :x! ) - after loc,subct,title were inserted - then I can successfully access 127.0.0.1:8000/loc/srv/subctg/title/
Anyone can shed some light? It looks like the urlpatterns need to be 'updated' each time a row is insterted in srv table.

You should just use something like this:
urlpatterns += patterns('',
url(r'^(?P<loc>\w+)/(?P<subctg>\w+)/(?P<title>\w+)/$',
'beta.views.queryFromIndexDeep'),
)
Using regular expressions to match your view is way easier, and recommended. In your view, the above would match a function defined like beta.views.queryFromIndexDeep(request, loc, subctg, title), from where you can continue to work with these variables to extract the relevant data from your defined models.

add a slugfield (unique) to your srv model and add a method to the model
def get_absolute_url(self):
return /yourapp/%s/ % self.slug
Then in urls use a pattern to match this
url(r'^srv/(?P<slug>[-\w]+)/$', yourgenericview),
Look into the django slugify snippit for fun http://djangosnippets.org/snippets/690/

Related

Is it required to add custom views in admin page in ModelAdmin class when we can do it normally by adding views in views.py and urls in urls.py?

According to django docs:
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
my_urls = [
url(r'^my_view/$', self.my_view),
]
return my_urls + urls
def my_view(self, request):
# ...
context = dict(
# Include common variables for rendering the admin template.
self.admin_site.each_context(request),
# Anything else you want in the context...
key=value,
)
return TemplateResponse(request, "sometemplate.html", context)
If I am not wrong, we can do the same thing by adding url in urls.py and the views in views.py as it is normally done then, what is the use of introducing this way? I am a newbie to django and I may be missing something here.
Can you please provide an example where we cannot do it in views.py and we must use the above method?
Any guidance/help would be appreciated.
I think I figured out, both of them can be used to do the same thing but the key difference is that the views which you write using above method will belong to admin app while the general views in views.py belongs to the particular app in you have written.
Hence, the url in ModelAdmin need to be called using name admin:url_name since the url goes as admin/my_views/ in given example.

Django Regular expression many slugs

I have the regular expression in my url that accepts pass one slug to my view, exemple:
127.0.0.1/cart/product_slug1
But I need a regex that accept pass one or more slugs, example:
127.0.0.1/cart/product_slug1/product_slug2/product_slug3/.../product_slugN
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(
r'^cart/add/(?P<slug>[\w_-]+)/$', views.create_cartitem,
name='create_cartitem'
),
It's possible send many slugs?
[UPDATE]: It seems that you cannot do that. Instead, you can place a catch all pattern and capture the whole url. Then inside your views you can split it by / and get the parameters you want. Something like this:
urlpatterns = [
url(
r'^cart/add/(?P<slugs>[\w_/-]+)/$', views.create_cartitem, name='create_cartitem'
),
And then in your views, do this:
def my_view(request, slugs):
slugs = slugs.split('/')
# now slugs is a list of strings
Note, however, that this is error prone since both cart/add/h/e/l/l/o and cart/add/hell//o//to/you are valid.
-- OLD ANSWER --
Sure you can, but you cannot use both named captured parameters with unnamed ones.
So, change your urls.py to this:
urlpatterns = [
url(
r'^cart/add/([\w_-]+)/([\w_-]+/)*$', views.create_cartitem, name='create_cartitem'
),
And inside your views.py, instead of kwargs (like slug you already have) you must use args (positional arguments, now you're gonna have a list of slugs). Like this:
def my_view(request, *args):
for arg in args:
print(arg)
Now if you type 127.0.0.1:8000/cart/add/argv/argvv/argvvv/, inside your views you get them as a list ['argv', 'argvv', 'argvvv'].

Django regex url not working

The http://127.0.0.1:8000/song/299d8fe1-7d9f-434a-ba64-94fb7a16b1a6/gives me the desired page based on the uuid of the song and works fine.
(It's the second url.)
Here is the urls.py
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^song/(?P<uuid>\S+)/$', views.song, name='song'),
--> url(r'^song/(?P<uuid>\S+)/song_info/$', views.song_info, name='song_info'),
)
The third url,
http://127.0.0.1:8000/song/299d8fe1-7d9f-434a-ba64-94fb7a16b1a6/song_info/
the one the arrow is pointing at, gives me a 404 error, with the message "No Song matches the given query."
I'm guessing there's an error with the regex, but I can't figure it out.
EDIT
Here are the views for both the song and song info:
views.py
imports....
#login_required
def song(request, uuid):
song = get_object_or_404(Song, uuid=uuid)
song_status = song.get_status()
form = SongInfoForm(initial={'song_info': song.song_info}, user=request.user)
return render(request, 'songapp/song.html',
{'form': form, 'song': song, 'song_status': song_status})
def song_info(request):
return render(request, 'songapp/song_info.html')
\S+ matches any sequence of characters, including '/'. So your second regex is matching the entire string of "299d8fe1-7d9f-434a-ba64-94fb7a16b1a6/song_info/" as the UUID parameter, and sending it to views.song, which unsurprisingly does not find a matching song.
You should make your regexes more discriminating:
url(r'^song/(?P<uuid>[\w-]+)/$', views.song, name='song'),
url(r'^song/(?P<uuid>[\w-]+)/song_info/$', views.song_info, name='song_info'),
Also, you should usually put your regexes in order of more specific to more general; Django matches in order, so if you had put song_info first that would also have solved your problem.
you should use this url
url(r'^song/(?P<id>[a-zA-Z0-9]{0,30}[^/]+)/song_info/$
Here, [^/] represents any type of character but /, and the + right after matches this class of character one or more times. You do not want the final / to be in the uuid var, so put it outside the parentheses

Making a Django URL pattern with a variable which isn't a integer

I was busy doing the Django tutorials and they explain how you can have url patterns which make it possible to pass information back to the functions in the view.py file. For example
urlpatterns = patterns('',
url(r'^some_view/(?P<number>\d+)', views.some_view, name = 'some_view')
and the integer in the url slot '(?Pnumber>\d+)' is passed to the some_view function in the file views.py. Apparently the d+ stands for decimal but what should it be if I want to pass a string variable back to the some_views function.
You need to use this partern: (?P<anystring>.+)
urlpatterns = patterns('',
url(r'^some_view/(?P<anystring>.+)', views.some_view, name = 'some_view')

creating custom item in ADMIN_MENU_ORDER

I'm having trouble understanding how to use the custom functionality of ADMIN_MENU_ORDER?
I want to do something like so -
ADMIN_MENU_ORDER = (
("Content", ("pages.Page", "blog.BlogPost",
"generic.ThreadedComment", ("Media Library", "fb_browse"),)),
("Site", ("sites.Site", "redirects.Redirect", "conf.Setting")),
("Users", ("auth.User", "auth.Group",)),
("MYAPP", ("View1", "app_view1")),
)
From what I gather I need to use redirects from URLs but where and how am I doing this? What I'm assuming is I'm doing this in MYAPP?
urls.py:
urlpatterns = patterns('',
url(r'^view1/$', 'View1', name='app_view1'),
)
And then generate that in my views.py?
class View1():
queryset = model.objects.all().values('fielda', 'fieldb', 'fieldc')
def get(self):
return queryset
My custom menu items still don't show up. I'm guessing I need to parse them into a template or return the results in a format that can be consumed by the mezzanine code? In which case what does that format need to be?
You've pasted an example right there in your question:
("Media Library", "fb_browse")
From the docs: http://mezzanine.jupo.org/docs/admin-customization.html#custom-items
It is possible to inject custom navigation items into the
ADMIN_MENU_ORDER setting by specifying an item using a two item
sequence, the first item containing the title and second containing
the named urlpattern that resolves to the url to be used.
There's no need for redirects. You just need to use the urlpattern names. Your urlpatterns weren't named, they'd look like:
urlpatterns = patterns('',
url(r'^view1/$', 'view1', name='my_view1'),
url(r'^view2/$', 'view2', name='my_view2'),
)
Then:
ADMIN_MENU_ORDER = (
...
("MYAPP", (("First", "my_view1"), ("Second", "my_view2"))),
)

Categories

Resources