Q:

Why can't I use model methods as defaults? What is self in Python/Django models anyway?

I have a very basic problem in understanding the behaviour of self.
Specifically, I don't understand why neither of the following two snippets of code work, the first one causing the interpreter to complain that 

self is missing as an argument,

the second that 

self couldn't be referenced.

class Model(models.Model)
    name = models.CharField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, default=gen_field())

    def gen_field(self):
        return self.name + 'something'

class Model(models.Model)
    name = models.CharField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, default=gen_field(self))

    def gen_field(self):
        return self.name + 'something'

The following code, which uses self as well, works fine:
class Model(models.Model)
    name = models.CHarField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, blank=True)

    def gen_field(self):
        return self.name + 'something'

    def save(self):
        self.auto_gen_field = self.gen_field()
        super(Model, self).save(*args, **kwargs)

Why does the self reference exists in one place but not in the other?
How do I fix the first two snippets?

A:

You're invoking the method at the time when the field is declared. At that point there is no self.
You don't want to do that anyway. Quite apart from any problems with self, doing so would return a static value for the default, so all instances would use the same value. That is why it is important to pass the callable: gen_field - not the result - gen_field().
(Note however that still won't work: the instance wouldn't be passed to the function because it's not being invoked as a method on an instance. Overriding save is the way to go.)

A:

self is by convention (it is really a name like any other, what matters is that it is the first argument of your class methods) a reference to the current instance of the class,  more or less like this in C++/Java.
Now, in 
class Model(models.Model)
    name = models.CharField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, default=gen_field())

When models.CharField(max_length=200, default=gen_field()) is evaluated there is no instance of the class, so you can't add a self in there.
It doesn't and can't possibly make sense.
Now, from: https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.Field.default

Field.default¶
The default value for the field. This can be a value or a callable
  object. If callable it will be called every time a new object is
  created.
The default cannot be a mutable object (model instance, list, set,
  etc.), as a reference to the same instance of that object would be
  used as the default value in all new model instances. Instead, wrap
  the desired default in a callable.

You want to pass a callable - which basically is akin to a function pointer.
What would work is:
def some_function():
     return something

...

auto_gen_field = models.CharField(max_length=200, default=some_function)

You can not, however, use a model method like gen_field() as default because Django does not pass a model instance as the first argument of the provided callable.
You have to override save.

