The Problem I want to solve is the following:
E.g. we have https://example.com/?id=e46Hd3cDe. But I want to make it look nicer so I want users to be able to go to this link: https://example.com/e46Hd3cDe and get the same HTML file returned.
How could I achieve this in Django?
If I would have to change something in the Apache config, how could I do that while testing Django locally? Currently, I test my Django website by calling python manage.py runserver and opening it at localhost:8000.
In Django, in your urls.py, define in url_patterns:
url_patterns = [
path('/<int:id>', view_name_goes_here),
]
Then, configure the corresponding functions in your views.py to accept the id parameter and get the corresponding object.
You don't need to modify your Apache config beyond adding in the WGSI setup for Django.
Related
Please tell me whether it is possible (if so, how) to use for pages each user subdomains. For example, now I have a URL of the form: http://hostname.com/user/1 I need to get http://username.hostname.com/
You have a number of options depending on how in-depth you want to go.
One option is to handle the routing at the web server level. Basically you will capture the subdomain part of the URL and rewrite it to a different location within your server.
For example http://username1.local.host/signin will be captured by your webserver and internally routed to a resource such as /username1/signin. The end user will subdomains but your code will handle url parts be none the wiser as to what has happened.
Your urls.py will then handle this like any normal request.
url_pattern = [
...
url(r'(?P<subdomain>[a-z]+)/sigin/$', 'view'),
]
For Nginx you will need to look into "subdomain to subdirectory re-writing".
I would personally use this option for what you have stated in your question. Whilst this method is a little more tricky to setup initially (keep at it until it works). It will be a lot easier to maintain and work with in the long run.
The other option is to handle the subdomains at the django level using a package such as Django Subdomains (I have used this one in the past and found it to be my preferred option (in terms of handling subdomains within django code)).
Without going into too much detail nginx will capture the subdomains and route all of it to django. Django will then handle the subdomains at the middleware level.
Personally I would use option 1 for your usage. Option 2 is if you want different apps on different domains for example: blog.local.host, support.local.host.
Consider using django-hosts
From docs:
# For example, if you own example.com but want to serve
# specific content at api.example.com and beta.example.com,
# add the following to a hosts.py file:
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'),
)
I have a django web app on A2hosting, where I am using .htaccess files and passenger_wsgi.py. It was working fine the last time I touched it, but then someone who had a look at it later informed me that it was broken.
I created a test situation to find the problem and here's the gist of it.
When I do a GET (to www.geo4ce.com/quiz/test_weird/), it goes to a page with a simple form that just has one input and a submit and an action that has "/quiz/test_weird/" and method="post". When I submit the form, the server expects the "quiz" part of the url to be referring to a path on the file server, can't find it and then logs an error that it can't find it. But, then it checks the test_weird part of the url against my django urls.py file, finds a different view for that and displays it.
A scenario that almost works properly is with www.geo4ce.com/quiz/test_hacked/, that has the same set up, except the form has action = "/anythinghere/quiz/test_hacked/". In this case, the "anythinghere" part of the url gets an error logged, since it doesn't exist on the file server, and then the /quiz/test_hacked/ part of the url works normally to get back to the original web page.
Anyone have any idea how I might be able to fix or debug this?
[EDIT]
I don't think it's the .htaccess file that's the cause. It looks something like this.
PassengerEnabled On
PassengerAppRoot /path/to/app/folder/
# Prevent Apache from serving .htaccess files:
<FilesMatch "^\.htaccess">
Order allow,deny
Deny from all
</FilesMatch>
deny from xxx.yyy.zzz
Apparently the issue is caused by a certain version of Passenger (with RoR). I've been told to switch to using FCGI.
The web app I am working on needs to perform a first-time setup or initialization,
where is a good place to put that logic? I dont want to perform the check if a configuration/setup exists on each request to / or before any request as thats kind of not performant.
I was thinking of performing a check if there is a sane configuration when the app starts up, then change the default route of / to a settings/setup page, and change it back. But thats like self-changing code a bit.
This is required since the web app needs settings and then to index stuff based on those settings which take a bit of time. So after the settings have been made, I still need to wait a while until the indexing is done. So even after the settings/setup has been made, any requests following, will need to see a "wait indexing" message.
Im using flask, but this is relevant for django as well I think.
EDIT: Im thinking like this now;
When starting up, check the appconfig.py for MY_SETTINGS, if it is not there
add a default from config.py and put a status=firstrun object on the app.config, also
change the / route to setup view function.
The setup view function will then check for the app.config.status object and perform
The setup of settings as necessary after user input, when the settings are okay,
remove app.config.status or change it to "indexing", then I can have a before_request function to check for the app.config.status just to flash a message of it.
Or I could use the flask.g instead of app.config to store the status?
The proper way is creating a CLI script, preferably via Flask-Script if you use Flask (in Django it would be the default manage.py where you can easily add custom commands, too) and defining a function such as init or install:
from flaskext.script import Manager
from ... import app
manager = Manager(app)
#manager.command
def init():
"""Initialize the application"""
# your code here
Then you mention it in your documentation and can easily assume that it has been run when the web application itself is accessed.
If I create an application and some controller, by default I will access it using:
http:// 127.0.0.1/application/controller/function
I want to change the behaviour of the URLs that I can access any controller by not asking for the application part. Using my example, I want to be able to access all the controllers of my app like this:
http:// 127.0.0.1 /application/controller/function1
http:// 127.0.0.1 /application/controller2/function2
http:// 127.0.0.1 /application/controller2/function3 (and etc.)
What I want to do is remove the need to indicate the application to be able to access all my controllers like this:
http:// 127.0.0.1/controller/function1
http:// 127.0.0.1/controller2/function2
http:// 127.0.0.1/controller2/function3 (and etc.)
Modifying my routes.py:
# routes.py
default_application = 'application'
default_controller = 'controller'
default_function = 'index'
I can access http://127.0.0.1/ and I am redirected to http://127.0.0.1/controller/index
But If I try to access other function I need to indicate the application.
I didn't find a good reference about how routes.py can be configured, and I think that I have to change this file to get what I want.
Anyone can help me?
Thanks!
The web2py URL rewrite functionality is explained in the book. Note, you have a choice between the newer (and simpler) parameter-based system and an alternative pattern-based system (which provides some additional flexibility for more complex cases). In your case, the parameter-based system would be easiest -- just include the following in your routes.py file:
routers = dict(
BASE = dict(
default_application = 'application',
default_controller = 'controller',
),
)
If you need additional help, I would recommend asking on the web2py mailing list.
I can't, for the life of me, get Django to find my JavaScript files! I am trying to plug in a custom widget to the admin page, like so:
class MarkItUpWidget(forms.Textarea):
class Media:
js = (
'js/jquery.js',
'js/markitup/jquery.markitup.js',
'js/markitup/sets/markdown/set.js',
'js/markitup.init.js',
)
css = {
'screen': (
'js/markitup/skins/simple/style.css',
'js/markitup/sets/markdown/style.css',
)
}
However, when this code is inserted on my admin page, all of the links are broken, I can't get to any of my JavaScript files. My settings file looks like this: http://pastebin.com/qFVqUXyG
Is there something I am doing wrong? I'm somewhat new to Django.
I guess you're using django-admin runserver to test your website. In that case, have a look at "How to serve static files" (but don't ignore the big fat disclaimer).
Once you're ready to deploy, this chapter contains all the information (provided you go the standard route of Apache/mod_wsgi)
I don't know what the "django way" to include js files is, but I just use a simple regular include in the template, its great since you can dynamically generate the location / filename for these.. oh and if you are using django's test server I don't know how to get it to recognize these or if it even can but all you need is to run an apache server on your local machine and then put the files in the localhost directory and you can include them through localhost by including their full path in the template (i.e., http://localhost/myfiledirectory/myfile.js), also something I do is use amazon s3 to host files since you then get a url for them on there (not that you asked about this but its a quick way to host files if you don't have apache running locally)
Basically, my understanding of Django is that it works differently than a PHP framework, for example, as the files for Django don't sit (or don't need to at least) in the web path (i.e. they do not need to be accessible through the host path but can be anywhere on the machine) this is good for providing extra security, etc but it also means, that to give files a url to download them they need to be in the web hosting path, others may know how to make django do this directly but my quick and dirty method of putting them on the localhost path will work if thats all you're after.