tags:

views:

73

answers:

2

I need some clear thinking on how to handle a save function on a django model. As you'll see below I am at a loss on how to do this elegantly. I'd like to pass the entire object to another module and analyze it there. My motivation for having the analysis broken out and not in models.py is that I will be frequently refining the analysis bit. Thanks.

models.py
from test_app.spam_analyzer import spam_checker
class SharedLink(models.Model):
    link = models.URLField()
    submitters_ip = models.IPAddressField()
    flag = models.CharField()
    def save(self, *args, **kwargs):
        self.flag = spam_checker(self)
        super(SharedLink, self).save(*args, **kwargs)

spam_analyzer.py
from test_app.models import SharedLink #this causes a "field not found" error
def spam_checker(SharedLink)
    submitters_ip = SharedLink.submitters_ip
    # see if this user's ip appears on a spam list
    # if it does flag it 'spam'
    return flag
A: 

I presume your error is caused by a circular import - that is, models.py imports spam_analyzer.py, and vice versa, so Python gets into a muddle. However with the code you've posted, there's no need to import SharedLink in spam_analyzer, since you pass it in as a parameter (although note that you're passing an instance, not the class itself, so you should really call the parameter shared_link for the sake of clarity).

An alternative would be to make the spam_checker function a method of the SharedLink class, so you could just call self.spam_checker() in your save() method.

Daniel Roseman
A: 

Check it at the form layer. You might call spam_checker from the clean() routines in your form when you first sight the sharedLink; then pass the flag through to the model with the link.

But possibly better, given that your spamchecker is under constant improvement, implement spamchecker as a flag() method on the model. Thus the flag will always use your most recent spam_checking algorithm.

class SharedLink(models.Model):
    link = models.URLField()

    @property
    def flag(self):
        return spam_check(self.link)
John Mee