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.
 
  • Locked thread
Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
Ohh, very handy this thread has come up. I've been looking at Django for a while, and I'm thinking of switching my project from CakePHP to Django - but I must admit I can't find any "nice" tutorials to get me started - Apart from the Django site and book, can anyone recommend any good resources for it for a beginner at Python?

Adbot
ADBOT LOVES YOU

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
I have a Django question: I'm re-building my Paste Monkey app from scratch using Django, and I found the Pygments syntax highlighting library. What I do with a paste is store the paste as plain text in the database, and I want to format it to the view. Here is my code:

code:
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from pastemonkey2.pastes.models import Paste, Language

from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter

def highlight(source, language):
    lexer = get_lexer_by_name(language, stripall=True)
    formatter = HtmlFormatter(linenos=True, cssclass="source")
    result = (source, lexer, formatter)
    return result

def show_paste(request, object_id):
    p = get_object_or_404(Paste, pk=object_id)
    p.formatted = highlight(p.paste, p.language)
    return render_to_response('pastes/paste_detail.html', {'object': p})
As you can see, I get the record from the DB and put it into p, and want to pass the paste and the language to the syntax highligher. The problem is that instead of passing in just the paste and the language, it has it as an object. So for example instead of passing 'python' it passes '<Language: python>'. Does anyone know a way to get round it?

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.

unclefu posted:

Are you doing something like {{ object.language }} in your template? If so you need to define a __unicode__ method in your Language class that returns whatever property contains the name.

Ok, I worked the language bit out by enclosing it in a str() but, the paste still comes out duff. I've checked the DB, and it's definitely plain text I should be passing with str(p.paste), but I am getting this instead:

code:
("from django.conf.urls.defaults import *\r\n
from pastemonkey2.pastes.models import Paste, Language\r\nfrom pastemonkey2.pastes.views import *\r\n\r\ninfo_dict = {\r\n 'queryset': 
Paste.objects.all(),\r\n}\r\n\r\nurlpatterns = patterns('',\r\n (r'^$', 'django.views.generic.list_detail.object_list',
info_dict),\r\n (r'^(?P<object_id>\\d+)/$', 
'pastemonkey2.pastes.views.show_paste'),\r\n)", <pygments.lexers.PythonLexer with {'stripall': True}>, 
<pygments.formatters.html.HtmlFormatter object at 0x88ca1ec>)
(btw the above comes out as one line, but i've broken it up here for easier reading)

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.

JoeNotCharles posted:

That's a 3-tuple - ("big string", <pygments Lexer object>, <pygments Formatter object>). If that's the contents of p.paste, you can get just the string with p.paste[0]. One idiom I like to use is "(pasteStr, lexer, formatter) = p.paste", which puts each part of the tuple into its own variable.

I presume you're supposed to use the lexer and formatter objects to turn the string into HTML, but you'll have to check the pygments docs to find out how.

Thanks JoeNotCharles, that got rid of the extra objects in the tupple - but yea, there still seems to be an issue with it not parsing the text and formatting it, I'll dig deeper on that one.

Edit: Oh man, I had a typo in my code that I completely missed as it didn't throw any errors :/ Well I've got it returning the code as parsed HTML now, but instead of rendering as HTML it renders as text (and weird in Firebug it looks fine). Thanks anyway, at least it pointed me in the right direction, and I learned a new thing in Python :)

Digital Spaghetti fucked around with this message at 16:55 on Nov 29, 2007

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.

unclefu posted:

Django templates automatically escape all output now. It sounds like you need to pass that highlighted output through the 'safe' filter. Here's more info about it.

Yea, after much searching I eventually found this, works a treat :)

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
I'm trying to set up Apache mod_python to serve my Django website, but I'm having problems getting it working.

To explain, my project is under /home/digitalspaghetti/workspace/digitalspaghetti. Here is my apache conf file:

code:
NameVirtualHost *
<VirtualHost *>
	ServerAdmin webmaster@localhost
	ServerName digitalspaghetti
	DocumentRoot /home/digitalspaghetti/workspace/digitalspaghetti/
  <Directory '/home/digitalspaghetti/workspace/digitalspaghetti/'>
	</Directory>
	<Location />
		SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE digitalspaghetti.settings
    PythonDebug On
	</Location>
</VirtualHost>
However, it won't load the config file:

code:
MOD_PYTHON ERROR

ProcessId:      16305
Interpreter:    'digitalspaghetti'

ServerName:     'digitalspaghetti'
DocumentRoot:   '/home/digitalspaghetti/workspace/digitalspaghetti/'

URI:            '/'
Location:       '/'
Directory:      None
Filename:       '/home/digitalspaghetti/workspace/digitalspaghetti/'
PathInfo:       ''

Phase:          'PythonHandler'
Handler:        'django.core.handlers.modpython'

Traceback (most recent call last):

  File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1537, in HandlerDispatch
    default=default_handler, arg=req, silent=hlist.silent)

  File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1229, in _process_target
    result = _execute_target(config, req, object, arg)

  File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1128, in _execute_target
    result = object(arg)

  File "/usr/lib/python2.5/site-packages/django/core/handlers/modpython.py", line 188, in handler
    return ModPythonHandler()(req)

  File "/usr/lib/python2.5/site-packages/django/core/handlers/modpython.py", line 152, in __call__
    self.load_middleware()

  File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py", line 27, in load_middleware
    for middleware_path in settings.MIDDLEWARE_CLASSES:

  File "/usr/lib/python2.5/site-packages/django/conf/__init__.py", line 28, in __getattr__
    self._import_settings()

  File "/usr/lib/python2.5/site-packages/django/conf/__init__.py", line 57, in _import_settings
    self._target = Settings(settings_module)

  File "/usr/lib/python2.5/site-packages/django/conf/__init__.py", line 85, in __init__
    raise EnvironmentError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e)

EnvironmentError: Could not import settings 'digitalspaghetti.settings' (Is it on sys.path? Does it have syntax errors?): No module named digitalspaghetti.settings
Can anyone with experience help get it set up.

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
Yea, I eventually tried it and it worked - although some of my 3rd party apps are having problems so I've had to disable them until I can work them out :(

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
I'm building a basic blog application in Django to replace Wordpress on my site eventually - it's nothing too fancy, but allows me to take PHP off my server. At the moment, I am building a blog app with 2 models, Category and Entry.

What I am trying to do is in my template for entry_detail.html (I'm using Generic views) I want to show in the sidebar a Related Entries section. What I'm having problems with is coming up with getting related entries from the DB. Here is my model code:

code:
from django.db import models
from django.db.models import permalink
from django.core import urlresolvers
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify

import datetime
# Create your models here.

class Category(models.Model):
    """ A Category is a way to manage the taxonomy of the site"""
    name=models.CharField(max_length=50) #The name of the category
    description=models.TextField()
    slug=models.CharField(max_length=75, null=True, blank=True)
    active=models.BooleanField()
    generate_feed=models.BooleanField()
    parent=models.ForeignKey('self', null=True, blank=True)
    def __unicode__(self):
        return self.name
    def save(self):
        if not self.slug:
            self.slug = slugify(self.name)
        super(Category, self).save()
    def num_entries(self):
        """Returns the number of entries in this category"""
        return self.entry_set.count()
    num_entries.short_description = "Number of Entries"
    class Meta:
        verbose_name_plural = 'Categories'
    class Admin:
        fields = (
                  ('Category Details', {'fields': ('name', 'description', 'parent',)}),
                  ('Category Settings', {'fields': ('active', 'generate_feed', 'slug',)}),
        )
        list_display = ('name', 'slug', 'active', 'generate_feed', 'num_entries', 'parent',)
        search_fields = ['name','parent']
        
PUBLISHED_CHOICES = (
    (0, 'Draft'),
    (1, 'Pending Review'),
    (2, 'Published'),
    (3, 'Archived'),
)

class Entry(models.Model):
    title=models.CharField(max_length=255)
    body=models.TextField()
    user=models.ForeignKey(User)
    slug=models.CharField(max_length=75, null=True, blank=True)
    pub_date=models.DateTimeField('date published')
    published=models.IntegerField(max_length=1, choices=PUBLISHED_CHOICES, verbose_name="Publishing Status")
    front_page=models.BooleanField()
    sticky=models.BooleanField()
    allow_comments=models.BooleanField()
    truncate=models.BooleanField()
    categories=models.ManyToManyField(Category, limit_choices_to = {'active':1})
    def save(self):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Entry, self).save()
    def __unicode__(self):
        return "%s" % self.title
    def was_published_today(self):
        """Flag to show if post was published today"""
        return self.pub_date.date() == datetime.date.today()
    was_published_today.short_description = 'Published today?'
    def get_absolute_url(self):
        """Get the URL of this entry to create a permalink"""
        return ('news-detail', (), {
            "slug": self.slug, 
            "year":self.pub_date.year, 
            "month":self.pub_date.strftime("%b").lower(), 
            "day":self.pub_date.day
            })
    get_absolute_url = permalink(get_absolute_url)
    class Meta:
        verbose_name_plural = 'Entries'
        ordering = ['-pub_date']
    class Admin:
       fields = (
                  ('Entry Content', {'fields': ('title', 'body', 'user', 'categories')}),
                  ('Date information', {'fields': ('pub_date',)}),
                  ('Publishing Details', {'fields': ('slug', 'published', 'front_page', 'sticky', 'allow_comments', 'truncate')}),
        )
       list_display = ('title', 'user', 'front_page', 'sticky', 'allow_comments', 'truncate', 'pub_date', 'published', 'was_published_today', )
       list_filter = ['pub_date', 'categories']
       search_fields = ['body', 'title']
       date_hierarchy = 'pub_date'
       ordering = ('pub_date',)
As you can see, the entry.categories is a ManyToManyField, so what I'm thinking is:

1) When the entry is displayed, do a query to grab all entries in the database.
2) Do a for loop on our entry to get each category is belongs to
3) Inside the loop, do another loop for each entry from the database
4) Inside that loop, compare the categories and see if they match, if they do add the entry to be an array
5) Stop after finding 5 matching and pass the array to the template

To me, that seems rather complicated, so I'm wondering anyone with more Django/Python experience if you could think of an easier design pattern for this. Another line I am thinking is doing a {% tag %} like I have with my latest entries (I do {% latest_entries "10" %}) but I'm not sure how I would pass in the id (as {% related_entries "object.id" %} would pass the string object.id and not the actual id??)

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
I ended up learning about inclusion tags:

code:
@register.inclusion_tag('blog/entry_related.html')
def get_related(entry):
    related = Entry.objects.filter(categories__in = entry.categories.all()).filter(published=2)[:5]
    return {'related': related }
and then of course the template:

code:
<h2>Related Entries</h2>
<ul>
	{% for r in related %}
		<li>{{r.title}}</li>
	{% endfor %}
</ul>
And within my code I can call it with {% get_related object %}

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
Another Django question from me:

I have a comment model I am building (yes I know Django has it's own Free comments, but it's poo poo) and what I want to do is have a template tag that displays the comment form for my entries. Here is the model at the moment, before I clean it up:

code:
from django.db import models
from django.db.models import permalink
from django.core import urlresolvers
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

from digitalspaghetti.blog.models import Entry

import datetime

class Comment(models.Model):
    author=models.CharField(max_length=50, default="Anonymous Chump")
    email=models.EmailField()
    website=models.URLField()
    comment=models.TextField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.IntegerField(_('object ID'))
    pub_date=models.DateTimeField('date published')
    is_private=models.BooleanField(default=False)
    is_authorised=models.BooleanField(default=False)
    def __unicode__(self):
        return self.author
    class Admin:
        pass
The problem is I don't know how to use New Forms within a template tag and be able to save the model data. If it was a view, I'd be fine, but since I can't have a save method as it's not a class, just a function I'm stumped :(

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.

deimos posted:

poo poo? Fairly undocumented perhaps, but they have everything, karma, adaptable moderation, akismet integration, what's poo poo about it?

Well maybe I'm a bit harsh - but what I mean is it isn't really extensible without having to go in a change some core code as far as I can tell - I want to remove the site field, and add a few other fields in so it's more like wordpress, unless you can tell me otherwise? And I don't see Askimet integration, which is what I am looking for but as you say the docs are pretty poor

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.

Mulozon Empuri posted:

The Django Book 1.0 is finally online! :woop:

I've made a PDF version of the online book, you can download it from http://digitalspaghetti.me.uk/2007/12/17/django-book-pdf

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.
This is more an appengine question, but does anyone know how I can parse XML in Google Appengine?

I'm not 100% sure my problem below is an appengine issue or a Python + AppEngine on windows issue?

I've googled and can't find any consistent help. Here is my code so far:

code:
from xml.dom import minidom
class MainHandler(webapp.RequestHandler):

  def get(self):
    userip = self.request.remote_addr
    if userip == "127.0.0.1":
        userip = "78.86.108.213"
    
    url = "http://api.hostip.info/?ip=%s" % (userip)
    result = urlfetch.fetch(url)
    if result.status_code == 200:
        location = minidom.parseString(result.content)
    
    path = os.path.join(os.path.dirname(__file__), 'templates/homepage/index.html')
    
    template_values = {
        'appName': 'jMaps Demos',
        'userip': userip,
        'location': location
    }
    
    self.response.out.write(template.render(path, template_values))
However I'm getting this traceback:

code:
Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 499, in __call__
    handler.get(*groups)
  File "C:\Documents and Settings\tpiper\My Documents\Aptana Studio\jmapsdemos\main.py", line 35, in get
    location = minidom.parseString(result.content)
  File "C:\Documents and Settings\tpiper\My Documents\Aptana Studio\jmapsdemos\xml\dom\minidom.py", line 1927, in parseString
    from xml.dom import expatbuilder
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1443, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1351, in FindAndLoadModule
    description)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1301, in LoadModuleRestricted
    description)
  File "C:\Documents and Settings\tpiper\My Documents\Aptana Studio\jmapsdemos\xml\dom\expatbuilder.py", line 32, in <module>
    from xml.parsers import expat
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1443, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1351, in FindAndLoadModule
    description)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1301, in LoadModuleRestricted
    description)
  File "C:\Documents and Settings\tpiper\My Documents\Aptana Studio\jmapsdemos\xml\parsers\expat.py", line 4, in <module>
    from pyexpat import *
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1443, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1351, in FindAndLoadModule
    description)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 847, in decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1301, in LoadModuleRestricted
    description)
ImportError: DLL load failed: The referenced assembly is not installed on your system.

Adbot
ADBOT LOVES YOU

Digital Spaghetti
Jul 8, 2007
I never gave a reach-around to a spider monkey while reciting the Pledge of Alligence.

chemosh6969 posted:

I'm guessing xml.dom isn't installed or it's not on the path, since it's giving an import error.

Yea, seems to be fine since switching into linux. Windows sucks :|

  • Locked thread