Forward url arguments to view in Django - python

I am trying to forward projects/1 to the view, for purpose of getting the project based on the id.
I have tried to change the regex, and the name.
Edit: But the issue is:
The id doesn't get forwarded (Or atleast not correctly) to the views, which results in the filter failing to find the Project based on the id.
Urls related to the 'Project':
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^project/(?P<project_id>([0-9]+))$', views.project, name='project'),
]
The view for the 'Project':
def project(request, project_id=1):
template = loader.get_template("project.html")
context = {
'project': Project.objects.filter(project_id=project_id)
}
return HttpResponse(template.render(context, request))

The regex seem a little incorrect to me, especially parentheses. Try this:
url(r'^project/(?P<project_id>[0-9]+)/$', views.project, name='project'),
UPDATE:
So you want to show only one project instead of several. In that case, change Project.objects.filter to Project.objects.get in your view.
Also, try this awesome django tutorial to learn the basics
Hope it helps.

Related

Django Slugs as principal url

I want to do the following, so that the profile of each registered user can be seen as follows:
http://127.0.0.1:8000/username/
I was able to achieve this, the problem is when wanting to create another page, for example
http://127.0.0.1:8000/explore/
Django consider "explore" as a user and throw me a 404 error.
this is my urls.py
urlpatterns = [
path("<slug:slug>/", PerfilView.as_view(), name="perfil"),
path("explore/", UserListView.as_view(), name="explore"),
]
Am I doing it the right way or am I unable to do this with django?
Regads
You should swap the two path(…): if you visit explore/ it will first match with the PerfilView since the slug can take 'explore' as value.
You thus should rewrite the urlpatterns to:
urlpatterns = [
# &downarrow; first explore
path('explore/', UserListView.as_view(), name='explore'),
path('<slug:slug>/', PerfilView.as_view(), name='perfil'),
]
This also means that you can not use explore as a slug here, since then it will match with the UserListView.

How to redirect in django while using django-hosts?

I'm using django-hosts package to manage content that's supposed to be set in various different subdomains. I started by making a view in which a form is used to change something. Once the form is validated and processed, user is supposed to be redirected to some other page. Looking through documentation there's an easy way to render():
settings_url = reverse('settings', host='dashboard')
return render(request, 'dashboard/settings.html', {'settings_url': settings_url})
However, there's no mention of redirect(). So how would I go about redirecting to somewhere else, instead of the usual return redirect("dashboard:settings")
myapp/hosts.py :
host_patterns = patterns('',
host(r'www', settings.ROOT_URLCONF, name='www'),
host(r'dashboard\.myapp\.com', 'dashboard.urls', name='dashboard'),
)
dashboard/urls.py
from .views import home, websitesettings
urlpatterns = [
url(r'^$', home, name='home'),
url(r'^settings/$', websitesettings, name='settings'),
]
Basically all I want is to redirect back to the same page after form is submitted (in the render example, I'm submitting a form to change certain website settings, which is a model on it's own, and then I want to redirect back to the same page after that).
Well took couple of different and convoluted tries, only to take a night off and come up with a solution that's ironically easy. Use of dajngos native redirect with django-hosts reverse function and it works like a charm:
from django_hosts.resolvers import reverse
return redirect(reverse('home', host='dashboard'))

Multiple django apps using same url pattern

I'd like to run two apps with the same url patterns. I would like to avoid having an app-specific slug like domain.com/pages/something-here or domain.com/blog/something-there.
I tried this:
# urls.py
urlpatterns = patterns('',
url(r'^$', 'my.homepage.view'),
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('pages.urls')),
url(r'^', include('blog.urls')),
)
# pages/urls.py
urlpatterns = patterns('',
url(r'^(.+)/$', views.page),
)
# blog/urls.py
urlpatterns = patterns('',
url(r'^(.+)/$', views.post),
)
My code doesn't work, whichever include comes first (here, pages.urls) works ok, other urls (for blog) throw 404.
Thanks in advance
EDIT: I did it like this: created glue.py in the same directory as settings.py. It will handle my homepage and this dispatcher view:
def dispatcher(request, slug):
try:
page = get_object_or_404(Page, slug=slug)
return render(request, 'pages/page.html', {'page': page})
except:
post = get_object_or_404(Post, slug=slug)
return render(request, 'blog/post.html', {'post': post})
I don't know if it's ok. I hope there is a better way.
Thanks for the comments.
I don't know if this is a better answer. But, if these situations are satisfied for you..
if your django app is based on django template rendering.
The url you are talking about, need not be accessed directly by typing the endpoint in the browser itself.
Then, maybe you could consider url namespaces and template redirections.
https://docs.djangoproject.com/en/1.11/topics/http/urls/#url-namespaces
This doesn't work because django urls are resolved in order, meaning that the first url that matches the regexp will be the resolved one. In your case, the the urls included from the blogs application will never be searched, as django already resolved the url on the pages includes line.
Also, the django url module is not supposed to know if a certain page or blog post exists, as i believe in your application this is determined with a database lookup.
The urls module just executes the view that is connected to the first regexp that matches.
You should change your logic, e.g. with perpending "blog/" to blog urls (what's wrong with that?)
url(r'^blog/', include('blog.urls')),
url(r'^', include('pages.urls')),
Notice that the i moved the blog url up, as most generic regxexp should always be the last to be tried by django url resolver.
Alternatively, you could code a proxy view that tries both blog posts and pages. but it doesn't seem the best way to do it to me.
How would you like this to work? They're both using the same URL (which of course is causing problems). How would a user get to a "page" rather than a "blog" or vice versa?
In general, you can't have overlapping URLs in your URL patterns (without including additional data).
EDIT:
So you want the first app to check if it has a view to match the URL and next to take over if the first doesn't? You could do something complicated like writing a "view matcher" to do want you want, but there are much more straigtforward solutions.
The easiest way would be to alter the slug generation function for one of your apps. Have one use some delimeter other than underscores, or always append the name of the app to the slug. This way you could find pages because their url would be "some-slug-page" and blogs would be "some-slug-blog", which you could then write a URL pattern for. If you don't want to add the entire URL, you can append/prepend just the first letter, or whatever you want.
Just think about a way that's acceptable to you to generate URLs for each app which, just by reading the URL, lets you know which app the page belongs to.

Django index page best/most common practice

I am working on a site currently (first one solo) and went to go make an index page. I have been attempting to follow django best practices as I go, so naturally I go search for this but couldn't a real standard in regards to this.
I have seen folks creating apps to serve this purpose named various things (main, home, misc) and have seen a views.py in the root of the project. I am really just looking for what the majority out there do for this.
The index page is not static, since I want to detect if the user is logged in and such.
Thanks.
If all of your dynamic content is handled in the template (for example, if it's just simple checking if a user is present on the request), then I recommend using a generic view, specificially the direct to template view:
urlpatterns = patterns('django.views.generic.simple',
(r'^$', 'direct_to_template', {'template': 'index.html'}),
)
If you want to add a few more bits of information to the template context, there is another argument, extra_context, that you can pass to the generic view to include it:
extra_context = {
'foo': 'bar',
# etc
}
urlpatterns = patterns('django.views.generic.simple',
(r'^$', 'direct_to_template', {'template': 'index.html', 'extra_context': extra_context }),
)
I tend to create a views.py in the root of the project where I keep the index view.

How can I get an accurate absolute url from get_absolute_url with an included urls.py in Django?

I've building a app right now that I'm trying to keep properly decoupled from the other apps in my Django project (feel free to lecture me on keeping Django apps decoupled, I'd be happy to learn more any/all the time).
My problem is this: The get_ absolute_url() method I've written is returning a relative path based on my view. I think it's wrong to have to add a special named view in the project urls.py just so I can have absolute urls in my app, and I can't figure out what I'm doing wrong. So if someone can help me out, I'll really appreciate it (and mention you when I release this sucker!)
I have a project-level urls.py that includes another urls.py based on the URL pattern like so (the names are verbose for this example only):
project-urls.py
urlpatterns = patterns('',
('^$', direct_to_template, {'template': 'base.html'}),
(r'^app', include('project.app.urls')),
)
app-urls.py
urlpatterns = patterns('',
url(r'(?P<slug>[-\w]+)?/?$', 'app.views.home', name='app_home'),
)
Now, in my Model, I have something like this:
class AppModel(models.Model):
title = models.CharField(_('title'), max_length=100)
slug = models.SlugField(_('slug'), unique=True)
#permalink
def get_absolute_url(self):
return ('app_home', None, {'slug': self.slug})
When I call {{ AppInstance.get_ absolute_url }} in the template, I get something like this:
/slug-is-here
Which is obvs not absolute & makes sense based on my urls.py. What should I change to get a real absolute url while keeping this app clean & not couple it too deeply w/the project?
Welp,
It turns out that when I was seeing this:
/slug-is-here
I should have looked closer. What was really happening was:
/app-pathslug-is-here
I was missing a trailing slash on my app's regex in my project urls.py.
So yea. let that be a lesson to y'all.

Categories

Resources