Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
bitprophet
Jul 22, 2004
Taco Defender

SlightlyMadman posted:

If you're going to use django though, you'd better do it the django way or it's going to hurt. I bet you capitalize your method names too, don't you?

Er, what? That's BS. As long as he imports his model classes into models.py, Django won't give a poo poo what files they're originally defined in. It's all just Python.

Adbot
ADBOT LOVES YOU

bitprophet
Jul 22, 2004
Taco Defender

JammyB posted:

I'm looking for a little advice on deploying some Django websites to an Ubuntu Server. Where exactly should each website live within the file structure?

I tend to follow a convention I first saw over in the Rails world and put things in /srv/django, e.g. /srv/django/example.com, /srv/django/example2.com and so forth.

Prior to this I did the same thing but with /opt instead of /srv; the two are largely interchangeable in my view, though the various filesystem hierarchy standards may disagree. Basically, any code or files that the server is "serving up" and doesn't have a predetermined, obvious location -- I'll stick into /srv/ somewhere, and that includes stuff like Django/Rails/etc Web application project folders.

Home directories are never, in my opinion, the right place to put anything except personal poo poo that has nothing to do with the actual server's mode of operation. It's just gross :(

Another bad choice is /var/www/sitename, as /var/www/ and/or its subdirectories are for Apache docroots and you never want to put non-CGI-ish code (i.e. PHP, actual CGI scripts, static files etc) into a place that could be served up by your Web server.

However, it may be a good idea to symlink a subdirectory of your Django project into a Web docroot -- for example, I tend to have a Django project directory structure like this:
code:
example.com
|-- __init__.py
|-- app.wsgi
|-- manage.py
|-- media
|   |-- css
|   |   |-- print.css
|   |   `-- screen.css
|   |-- img
|   |   |-- foo.jpg
|   |   `-- bar.png
|   `-- js
|       |-- main.js
|       `-- datepicker.js
|-- app1
|  `-- [app stuff here]
|-- app2
|  `-- [ditto]
|-- app3  
|  `-- [ditto]
|-- settings.py
`-- urls.py
and then symlink the media directory (which would be in /srv/django/example.com/media) as, say, /var/www/example.com (so that the Web server can see e.g. /var/www/example.com/js/. This lets Apache serve my static media while keeping the Python out of the docroot and keeping the Python and media files together in one (source controlled) directory structure. (And since this approach is flexible, it can change to accommodate whatever URL structure you want to appear.)

bitprophet fucked around with this message at 01:11 on Sep 8, 2009

bitprophet
Jul 22, 2004
Taco Defender

geera posted:

This may have been asked/discussed before, but how do you approach organizing the "main" part of the website in your code? Do you make an app and call it something like "site" or "main" or whatever, and put the majority of your work in that app's directory, or do you have some other method?

What bosko said. Personally, I tend to make a "base" app, which often has no models, views or URLs and is just there for stuff like context managers and custom templatetags and such -- keeping these in an "app" allows Django's app-centric loaders to pick them up correctly.

I sometimes also throw "top level" crap (e.g. the homepage URL/view/template of a multi-app site, etc) into this app as well, though. Keeps the top level directory a bit neater. If I go too far down that road I'll even put my settings.py and top level urls.py in this folder too -- since you can just set your DJANGO_SETTINGS_MODULE to 'myproject.base.settings' without issue -- but that might be a bit much, still on the fence myself as to whether it's really worth it.

bitprophet
Jul 22, 2004
Taco Defender

SlightlyMadman posted:

I really like this scheme, and have adopted it for a new project I just set up. Where do you keep your templates? I'm going to put them in /srv/django/example/templates, but I was curious if you had an opinion on that.

Huh, I totally omitted templates in that example. Probably because the project I was basing it on uses per-app template loading (see the 2nd-mentioned loader type in that section.) I don't do as much Django lately as I'd like, but when I was last setting up new projects I did lean in that direction (per-app template folders.)

While you have to name templates globally unique names, or else stick them into silly subfolders (i.e. root/app1/templates/app1/blah.html, referred to as "app1/blah.html" in the code just like with project-wide templates) it still means that your individual apps can be broken out, given to someone else, or otherwise packaged nicely. (king_kilr, has anyone done any interesting work in this area recently?)

Anyway, project-wide templates aren't bad per se -- my single biggest Django app does it, though that's mostly a function of its age -- just slightly less flexible in terms of future refactoring of apps.

bitprophet
Jul 22, 2004
Taco Defender

duck monster posted:

installing apps in /srv or /django or any other such top level directory will deeply annoy most sysadmins [...]

I'm lucky enough to admin my own systems and/or generally work in environments where the sysadmin is actually told what the system will be used for and can tailor the backup/mount scheme accordingly. (I also tend to use a one-big-partition setup unless the system has obvious needs otherwise, because I've run into other peoples' poor partition size planning way more often than I run into situations involving SANs or needing specific mount flags. v:shobon:v yes I work in a small/medium sized web shop, how'd you guess?)

Out of curiosity, where would a POSIX or LFHS compliant location for "web apps" like this be? Please don't say something horrid like /home/django/myapp :cry: I'm guessing /var/django/myapp or /opt/django/myapp?

bitprophet fucked around with this message at 21:50 on Oct 20, 2009

bitprophet
Jul 22, 2004
Taco Defender

deimos posted:

The correct place for that stuff IS /srv according to the LFHS.

http://www.tldp.org/LDP/Linux-Filesystem-Hierarchy/html/srv.html

VINDICATION

I thought there was some reason I moved to /srv from /opt, other than "well that's how the rails guys at work do it". Maybe I actually looked it up :v: (No, I don't remember these things very well.)

duck monster's point may still hold for non Linux systems, though, but that doesn't describe me so eh.

bitprophet
Jul 22, 2004
Taco Defender

agscala posted:

How do you all serve your images and css and other files? I suppose I could use another server but I feel like there is a better way

Any serious production server that sees heavy traffic will use another server, which is why that's the "default" in the settings.py commentary.

For something not quite so heavily trafficked, what I usually do is keep them in source control with everything else in a media or similar directory at the top level, then symlink that into my static Apache docroot.

Then just tell Apache to toss the entire URL space to e.g. mod-wsgi, with a Location block saying "...well, except for /media/, just serve that normally".

I posted another example of this earlier in the thread :) a page or 2 back iirc.

bitprophet
Jul 22, 2004
Taco Defender

ATLbeer posted:

Hmm.... Might be a good suggestion for Django to throw a exception Warning for using an ORM Syntax that isn't 100% compliant against all backends.

No, I think what king_kilr was trying to say is that the string values in an extra() clause like that, are all being inserted into the raw SQL, and you were trying to treat them like they were still ORM syntax or something.

Put another way, it's doing SELECT blah, blah,blah, <dict key here> AS <dict value here> FROM tablename WHERE ...". So, extra(select={'lower_name': 'lower(profile__name)'}) is translated into something like SELECT blah, blah,blah, lower_name AS lower(profile__name) FROM tablename WHERE ...".

Which doesn't make any sense, as you can see, because at that point we're talking SQL, not Django ORM keyword-argument stuff. There's no profile__name column.

However, if I'm right, you could do something like extra(select={'lower_name': 'lower(profiles.name)'}), provided you're also using the right stuff to get the profiles table joined into the query so that it forms legal SQL.

bitprophet
Jul 22, 2004
Taco Defender

SlightlyMadman posted:

Works great, but I can't figure out how to print headers. I've tried "for col,val in row.0.itmes" and things like "for col in row.0.keys" or "for col in row|first" but none of them seem to work. Any ideas? I'm sure it's something obvious, since the data is easily available.

First, what exactly does your rows data stricture look like? A list of dicts? And what Django version are you using?

Prior to, I think, Django 1.2 (which is only in alpha or beta as of yet) doing {% for x,y,z in iterable %} was not possible, and your other attempts don't make syntactical sense given a list of dicts.

For reference, the pre-1.2 method of iterating over a dictionary looks like this:
code:
{% for tuple in mydict.items %}
Key: {{ tuple.0 }}<br />
Value: {{ tuple.1 }}<br />
{% endfor %}
So if your rows is a list of dicts ([{'a': 'b', 'c': 'd'}, {'foo': 5}]) you would replace your for loop with the above.

bitprophet
Jul 22, 2004
Taco Defender

king_kilr posted:

Unpacking in templates has worked since before 1.0.

I must be thinking of the updated if tag, then.

And I did the bulk of my Django work well before 1.0, so don't be talking like 1.0 was all that long ago, sonny :bahgawd:

bitprophet
Jul 22, 2004
Taco Defender

ATLbeer posted:

An MySQLdb.OperationalError is thrown. That's not a problem until you try to catch it. MySQLdb.OperationalError is WAY too broad.

This poo poo (exceptions which are far, far too generic) pisses me off so much. I run into it in a few other pieces of software which my code is a client of, and boy howdy does it make my life difficult :argh:

You didn't mention this but sometimes, if you're lucky, you can introspect the exception's string value or other elements (depends on who wrote the exception and what they do with it) and derive additional meaning from that. Though I still find it nasty to have to hard-code that sort of comparison.

bitprophet
Jul 22, 2004
Taco Defender

taqueso posted:

I added this line to TEMPLATE_LOADERS

Surely you meant TEMPLATE_CONTEXT_PROCESSORS? :)

bitprophet
Jul 22, 2004
Taco Defender

deimos posted:

I really wish they'd do decent explanation of their rationale, my work is looking at Drupal for a bunch of poo poo which I think it'll be a terrible fit for which a framework (I am partial to django but I've said use anything) would be a much better fit. If I could point to an article or blog post or blurb with their rationale I would have some ground on my arguments.

A year old, but this post goes into some high level info about that. It's from back when they were "just" doing the AV Club port, but I assume the same general ideas applied to the main site's switcheroo as well.

bitprophet
Jul 22, 2004
Taco Defender

Sock on a Fish posted:

The problem is, when I run that one big function, the actions are only performed on the primary_host. Am I doing this wrong, or is this a limitation of fabric?

Limitation of Fabric: http://code.fabfile.org/issues/show/21 (a generic ticket, but covers this overall issue to some degree.) There will be some way to do it in the future (e.g. execute('function_name', ['host', 'list'])) but right now it's not easily possible.

You can fake it on your own for the time being by routing around the main execution loop: when run() and sudo() execute, they actually just check env.host_string. Multi-host execution (either manual or in Fabric's own main loop) is thus just effected by looping over a host list and setting that variable, then calling the task function.

So you could do e.g.
code:
from fabric.api import *

def go():
    # single host crap
    with settings(host_string='primary_host'):
        primary_host_only1() 
        primary_host_only2() 

    # multiple host crap
    for host in ['host1', 'host2', 'primary_host']:
        with settings(host_string=host):
            whole_cluster1()
            whole_cluster2()
            whole_cluster3()

def primary_host_only1():
    # crap that should only run on the single host

def primary_host_only2():
    # crap that should only run on the single host, part 2

def whole_cluster1():
    # crap that applies to everyone

def whole_cluster2():
    # crap that applies to everyone, part 2

def whole_cluster3():
    # crap that applies to everyone, part 3
Then invoke as:
code:
$ fab go
Note lack of any decorators or roles -- you're driving the "host list" mechanisms yourself here so they're not necessary.

Hope that makes some sense.

bitprophet
Jul 22, 2004
Taco Defender

Sock on a Fish posted:

Perfect sense, thanks. That reminds me of figuring out that the cd() context manager doesn't process absolute paths correctly, so before every cd('/some/abs/path') I'd have to set env.cwd to ''.

Hmm. That should only be the case if env.cwd is set to a non-empty value beforehand, such as if you were to call cd within another cd block. Can you verify whether that's what's going on?

Edit: If we have to do more than another back-and-forth on this, given it's not that Django related, maybe I should make a Fabric thread. Then again I can't imagine that many goons use it, so maybe we should just take it to email or PM.

bitprophet
Jul 22, 2004
Taco Defender

Sock on a Fish posted:

Oh yeah, it was a cd within a cd. I had some functions that were executing other functions within a cd context, and within those functions themselves there was a cd context specified as well. That really threw me, I assumed that any path starting with '/' would be interpreted as absolute.

Thanks, that makes sense now, and I agree that your assumption should have been correct. Ticket :)

bitprophet
Jul 22, 2004
Taco Defender

NoDamage posted:

(django-mingus, the first installation step in a loving blog shouldn't consist of installing 30 other plugins)

In its author's defense, the point of Mingus is to embrace the Django "reusable apps" philosophy. It's not that they're plugins to some core app, it's that the core app is simply a tiny bit of glue to hold all of the individual components together.

So where e.g. Wordpress core implements comments, static pages, permalinks, RSS feeds, and so forth, and then has plugins, Mingus is just a collection of what its author perceives to be the best available Django comments app, permalink app, RSS feed app, etc. So to knock it for "requiring a bunch of plugins" is to miss the point of the app.

At least, that's my understanding; I haven't used it myself, only read up on it a bit. I think king_kilr has though?

bitprophet
Jul 22, 2004
Taco Defender

king_kilr posted:

You shouldn't be using gunicorn in place of nginx, you should use it in addition to nginx in replacement of mod_wsgi.

People respond better if you tell them why something is instead of just dictating it ;)

GUnicorn is intended to be used behind a "real" Web server that is better able to handle actual browser-based clients, such as Apache or NginX. GUnicorn's design is such that it assumes the clients speaking to it will be fast -- see GUnicorn's design doc and also the PHILOSOPHY document for the original Unicorn project.

So while yes, it does speak HTTP, it's supposed to be paired up with some sort of general-purpose frontend server and not run standalone.

bitprophet
Jul 22, 2004
Taco Defender
You can also use Fabric and its Django support for this.

It's been a while since I used Django so I don't remember if setup_environ is effectively the same as setting DJANGO_SETTINGS_MODULE, but either way, assuming your project is in the PYTHONPATH, you could do something like:
code:
from fabric.contrib import django
django.project('yourapp')
from yourapp.models import SomeModel

def import():
    # Use SomeModel to import data somehow
This will IIRC be less boilerplatey than a real management command, but is obviously about the same amount of effort as what duck monster is doing above (though you'd have the other stuff in Fabric at your disposal, e.g. ready-made args/kwargs without doing your own optparsing, etc -- which may or may not matter to you).

bitprophet
Jul 22, 2004
Taco Defender

duck monster posted:

Whats peoples vibe on using passenger for serving django? The site seems to claim its a bit dicky, but people seem to be having good times with it too. Thoughts?

Reasonably sure the only people using Passenger for its WSGI capabilities are those who want a single backend server running both Rails and Django child processes. Which probably isn't a ton of folks :) (Not zero...just not many.)

bitprophet
Jul 22, 2004
Taco Defender

Captain Capacitor posted:

I'm using Carbon and Whisper

:hfive:

I'm currently experimenting with collectd + Carbon/Whisper/Graphite (+ Nagios) for a monitoring stack. It's pretty nice so far.

Are you using Graphite at all or just the Carbon/Whisper components? If the latter, curious why.

bitprophet
Jul 22, 2004
Taco Defender
Don't usually pimp it here but anybody using Fabric for their deploys/provisioning/whatever, should note that 1.1 just came out with namespaces and @task decorators, plus more. :toot: yoink

Anybody not using Fabric for deploys is...lame. LAME! or may just have a different use case and that's cool too, really

bitprophet
Jul 22, 2004
Taco Defender

RobotEmpire posted:

I can verify that Fabric 1.1 is baller. The namespacing is sexyyyyyyyyyyyyyyyyyyyyyyyyyyyy and ridiculously useful. The @task decorator is good too.

Yea I think out of all the feature releases in the last couple years this one easily has gotten the most specific buzz. Feels good man. And lots more to come :)

Think the next release (which may be soon) will add some more namespacey things like task aliasing (e.g. @task(aliases=['foo', 'f'])\ndef foobar: pass being callable as "f", "foo" or "foobar") and default tasks (so a module can designate one of its tasks to be called if you specify only the module name).

bitprophet fucked around with this message at 07:24 on Jul 1, 2011

bitprophet
Jul 22, 2004
Taco Defender

MonkeyMaker posted:

Hey, me too! Look for the dude giving out djangopeople.me stickers (I know, how descriptive!)

I'm here too :)

bitprophet
Jul 22, 2004
Taco Defender

MonkeyMaker posted:

If anyone wants a DjangoCon 2011 t-shirt, they're on sale for $20. I'm willing to pick them up for you, just Paypal me cost + shipping. hit me on twitter at @kennethlove for fastest responses.

Say, didn't Steve Ivy say yesterday that you wanted to meet up with me? EDIT: No, wait, that was some other guy. I think you still said you wanted to say hi though :v: I'm in the middle rear of the lightning talks room at the moment...

bitprophet
Jul 22, 2004
Taco Defender

IsotopeOrange posted:

The new Heroku for Django is Heroku: http://devcenter.heroku.com/articles/django

Why would you link that and not the actually pretty great blog post introducing it? :D

As a Pythonista I think this is one of the best descriptions of the language, community and ecosystem ever.

Adbot
ADBOT LOVES YOU

bitprophet
Jul 22, 2004
Taco Defender

Hanpan posted:

Any Django devs in the UK recommend any hosting? I've been using Kutoken but I'm not all that impressed.

Hopefully you're already aware of it, but ep.io (a PaaS) is UK-based. EDIT: Oh right, they're still invite-only. Still :)

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply