title: How to override the model.Manager.create() method in Django?
body: <p>I have plenty of <code>Hardware</code> models which have a <code>HardwareType</code> with various characteristics. Like so:</p>
  
  <pre><code># models.py
  from django.db import models
  
  class HardwareType(model.Models):
      name = models.CharField(max_length=32, unique=True)
  
      # some characteristics of this particular piece of hardware
      weight = models.DecimalField(max_digits=12, decimal_places=3)
      # and more [...]        
  
  class Hardware(models.Model):
  
      type = models.ForeignKey(HardwareType)
  
      # some attributes
      is_installed = models.BooleanField()
      location_installed = models.TextField()
      # and more [...]
  </code></pre>
  
  <p>If I wish to add a new <code>Hardware</code> object, I first have to retrieve the <code>HardwareType</code> every time, which is not very DRY:</p>
  
  <pre><code>tmp_hd_type = HardwareType.objects.get(name='NG35001')
  new_hd = Hardware.objects.create(type=tmp_hd_type, is_installed=True, ...)
  </code></pre>
  
  <p>Therefore, I have tried to override the <code>HardwareManager.create()</code> method to automatically import the type when creating new <code>Hardware</code> like so: </p>
  
  <pre><code># models.py
  from django.db import models
  
  class HardwareType(model.Models):
      name = models.CharField(max_length=32, unique=True)
  
      # some characteristics of this particular piece of hardware
      weight = models.DecimalField(max_digits=12, decimal_places=3)
      # and more [...] 
  
  class HardwareManager(models.Manager):
      def create(self, *args, **kwargs):
          if 'type' in kwargs and kwargs['type'] is str:
              kwargs['type'] = HardwareType.objects.get(name=kwargs['type'])
          super(HardwareManager, self).create(*args, **kwargs)       
  
  class Hardware(models.Model):
      objects = HardwareManager()
  
      type = models.ForeignKey(HardwareType)
  
      # some attributes
      is_installed = models.BooleanField()
      location_installed = models.TextField()
      # and more [...]
  
  # so then I should be able to do:
  new_hd = Hardware.objects.create(type='ND35001', is_installed=True, ...)
  </code></pre>
  
  <p>But I keep getting errors and really strange behaviors from the ORM (I don't have them right here, but I can post them if needed). I've searched in the Django documentation and the SO threads, but mostly I end up on solutions where:</p>
  
  <ul>
  <li>the <code>Hardware.save()</code> method is overridden (should I get the <code>HardwareType</code> there ?) or,</li>
  <li>the manager defines a new <code>create_something</code> method which calls <code>self.create()</code>.</li>
  </ul>
  
  <p>I also started digging into the code and saw that the <code>Manager</code> is some special kind of <code>QuerySet</code> but I don't know how to continue from there. I'd really like to replace the <code>create</code> method in place and I can't seem to manage this. What is preventing me from doing what I want to do?</p>