Different URL config depending on domain in Django - django

In Mezzanine there are two different URLs that you could use depending what content you want to be displayed. Is there a way to check inside the urls.py if the active domain is on a subdomain or just the "regular" domain?
This is the two different styles:
url('^$', direct_to_template, {'template': 'index.html'}, name='home'),
url('^$', mezzanine.blog.views.blog_post_list, name='home'),
I haven't found a solid way for this yet. I want to display blog_post_list if I am on a subdomain (wildcard / e.g. sub.example.com) and index.html if I am on the "main" domain (e.g. example.com)

No, the urls.py is loaded when your app boots up and only looks at the path. The current URL is part of the request objects, that the Middleware and the View receives.
However, you could use a view to delegate the request, based on the URL path.
url('^$', my_view, name='home')
And the view could use the current request object to delegate to one of the two subsequent views.
def my_view(request):
if 'something' in request.META['HTTP_HOST']:
return something_view(request)
else:
return another_view(request)
However, there is an app to do what you want to do, django-hosts. It allows to load different urls.py files based on the host.
from django_hosts import patterns, host
host_patterns = patterns('path.to',
host(r'api', 'api.urls', name='api'),
host(r'beta', 'beta.urls', name='beta'),
)

Related

i am facing issue to add path to product urls.py file ,i dont know how

```
I am creating CRUD for categories I make a CategoriesViewSet.
on the other hand, I register the router as default in urls.py(Products) for viewset of categories but I don't know how to add a path into the product => urls.py and also the path I want to include into the core url.py file.
product => urls.py
router =routers.DefaultRouter()
router.register(r'categories', CategoryViewSet)
urlpatterns = [
path('list/',ProductList.as_view(),name="View Product"),
path('add/',AddProduct.as_view(),name="Create Product"),
path('<int:pk>/',ProductDetails.as_view(),name="product_detail"),
# path('categories/', CategoryViewSet.as_view({'get':'list'}))
path(r'^', include(router.urls)),
re_path(r'categories/', CategoryViewSet.as_view({'get':'list'}),
name='product-detail')
]
Core => urls.py
path('admin/', admin.site.urls),
path('api/product/', include('products.urls')),
path('api/user/', include('user.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns = format_suffix_patterns(urlpatterns)
I don't think you have a clear idea of what Routers do in Django.
From DRF's official documentation:
Some Web frameworks such as Rails provide functionality for
automatically determining how the URLs for an application should be
mapped to the logic that deals with handling incoming requests.
REST framework adds support for automatic URL routing to Django, and
provides you with a simple, quick and consistent way of wiring your
view logic to a set of URLs.
This line:
router.register(r'categories', CategoryViewSet)
according to Django REST Framework's (DRF) documentation, generates 2 URL patterns:
categories/ - Return the list of categories
categories/{pk}/ - Return category with specified primary key (pk)
You don't need to add those again in Product's urls.py. You can either only specify the router.register(...) method, or manually add them like that:
path('categories/', CategoryViewSet.as_view(), name='product-detail')
It works. In my view I implemented and it works that's why I am asking First of all we have to add the
import [re_path and include] in the Urls.py (Products)
then we have to add--------------------
~the code will be added in the urls.py(Products) below the import library.
router = routers.SimpleRouter()
router.register(r'', CategoryViewSet, 'categories')
in Url Patterns~
re_path(r'^categories/',include((router.urls,'categories'),namespace='categories'))
it works.

multilingual django cms site: seo friendlier home pages (redirects)

NOTE / EDIT: As I've learnt, the default behaviour is ok SEO wise (one redirect is allowed...multiple is no good). So this is a bit of an overkill.
If my django-cms site is multilingual, visiting domain.com always redirects to domain.com/default-language/.
Is there a preferred way/package to make this behaviour go away?
Reason I want it are mainly because of SEO. Best solution would be:
domain.com => no redirect
domain.com/default-lang/ => redirect back to domain.com
domain.com/other-lang/ => stay as is, as there is translated content
Example: http://www.parkhotel-bellevue.ch/ redirects to http://www.parkhotel-bellevue.ch/de/, which is what I dont want. http://www.parkhotel-bellevue.ch does it correctly, now.
NOTE: this question is about django-cms, not django alone.
What if you put your Index url in root conf, and all your other pages under i18n_patterns ?
urlpatterns = [
url(r'^$', Index.as_view(), name='index'),
]
urlpatterns += i18n_patterns('',
url(r'^', include('cms.urls')),
)
This way, your root URL won't redirect to language specific URL.
For the second part of your question, you could try the following solutions:
If you have a limited, fixed set of languages, you can hardcode the redirects on your webserver conf (or in your django urls).
If you don't want to hardcode these redirects, maybe including your Index view in your i18n_patterns as well could do the trick
Something like:
# views.py
class Index(View):
def dispatch(self, request, *args, **kwargs):
if request.path != '/':
return redirect('/')
return super().dispatch(request, *args, **kwargs)
# urls.py
urlpatterns = [
url(r'^$', Index.as_view(), name='index'),
]
urlpatterns += i18n_patterns('',
url(r'^$', Index.as_view(), name='index'),
url(r'^', include('cms.urls')),
)
EDIT:
Another option could be to use your own LocaleMiddleware by subclassing the one from django.
The redirection part seems to happen here: https://github.com/django/django/blob/master/django/middleware/locale.py#L29

What takes priority of urls out of Django and AngularJS?

I am using Django with Angular... When I refresh my pages, I would prefer Angular to handle routing. So I need to render layout.html (via django), and after that let Angular manage the urls and routing to the correct controller.
For example in Django:
urls.py:
urlpatterns = patterns('',
url(r'^api/', include(v1_api.urls)),
url(r'^.*$', 'home.views.index'),
)
views.py
def index(request):
return render(request, 'layout.html', {})
But the priority of Django is not according to the number of lines written. Because now after refreshing, the urls that start with api, render index as well. It means Django didn't understand that the urls that start by api have higher priority.
So, whats priority of urls in Django, and has using Angular changed this?
Django will always return the first matching pattern.
i found the solution:
in url.py i changed reg-exp, instead of
url(r'^.*$', 'home.views.index'),
i used :
url(r'^.*/$', 'home.views.index'),
now if Django didn't find any matches, shows index.

Django URL changes but doesn't render the proper view

I have a url setup with the following view (the url is in the app and the app urls are included in the project):
url(r'^details/(?P<outage_id>\d+)/$', 'outage.views.outage_details'),
def outage_details(request, outage_id=1):
outage_info = Outages.objects.filter(id=outage_id)
return render_to_response('templates/outage/details.html', {'outage_info': outage_info}, context_instance=RequestContext(request))
When I click on the link from http://localhost:8000 the url in the browser changes to http://localhost:8000/outage/details/1 as it should, but the view doesn't render the right template. The page stays the same. I don't get any errors, the url changes in the browser but the details.html template doesn't render. There is an outage in the DB with an ID of 1.
Any thoughts?
The regular expression r'^details/(?P<outage_id>\d+)/$' does not match the URL http://localhost:8000/outage/details/1. However, it should match the expression r'^outage/details/(?P<outage_id>\d+)/$'.
Perhaps, you can post your entire urls.py to find out which view is actually being called, since you don't get any errors. I suspect your home page is being called for all URLs.
Here is my url setup:
project/urls.py
urlpatterns = patterns('',
url(r'^$', 'outage.views.show_outages'),
url(r'^inventory/', include('inventory.urls')),
url(r'^outage/', include('outage.urls')),
url(r'^login', 'django.contrib.auth.views.login', {'template_name': 'templates/auth/login.html'}),
url(r'^logout', 'django.contrib.auth.views.logout', {'next_page': '/'}),
url(r'^admin/', include(admin.site.urls)),
)
outage/urls.py
urlpatterns = patterns('',
url(r'^', 'outage.views.show_outages'),
url(r'^notes/(?P<outage_id>\d+)/$', 'outage.views.outage_notes', name='notes'),
)
I have since changed the details to notes, since I had another page in a different app with a details url and I didn't want it somehow confusing things.

What's the best way to map the main urls in a django project?

I've got a django project that contain some apps. The main urls.py includes the urls.py from the apps I've enabled, and all is good.
Now I want to configure the project so that when you go to http://testsite/, you'll get the same page that you get when you go to http://testsite/app/.
I can do this by duplicating the corresponding line in the apps urls.py in the projects urls.py, but this feels dirty.
Anyone know a better way?
Set up a redirect_to from the first url to the second, ie:
from django.conf.urls.defaults import patterns, url, include
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
# Example:
url(r'^$', redirect_to, {'url':'/app/'}),
url(r'^app/', include('app.urls')),
# ...
)
HTH
A redirect is the way to go, because you don't want multiple canonical URLs for the same resource (wastes Google juice). Ideally, you should do the redirect as close to the edge of your stack as possible to conserve server resources. So you can do a Django redirect_to urlconf entry, but you'd be better off with an Apache or nginx or insert-your-webserver-here redirect, so the initial request never has to hit Django at all.