Django - override get_or_create with models.py

I have a class in which I want to override a method get_or_create. Basically, if my class does not save the answer, I want it to execute some kind of process in order to get the answer, and it is not provided. A method is really a method get_or_retrieve. So the class:

class P4User(models.Model):
  user      = models.CharField(max_length=100, primary_key=True)
  fullname  = models.CharField(max_length=256)
  email     = models.EmailField()
  access    = models.DateField(auto_now_add=True)
  update    = models.DateField(auto_now_add=True)

  @classmethod
  def get_or_retrieve(self, username, auto_now_add=False):
    try:
        return self.get(user=username), False
    except self.model.DoesNotExist:
        import P4
        import datetime
        from django.db import connection, transaction, IntegrityError
        p4 = P4.P4().connect()
        kwargs = p4.run(("user", "-o", username))[0]
        p4.disconnect()
        params = dict( [(k.lower(),v) for k, v in kwargs.items()])        
        obj = self.model(**params)
        sid = transaction.savepoint()
        obj.save(force_insert=True)
        transaction.savepoint_commit(sid)
        return obj, True
    except IntegrityError, e:
        transaction.savepoint_rollback(sid)
        try:
            return self.get(**kwargs), False
        except self.model.DoesNotExist:
            raise e

  def __unicode__(self):
    return str(self.user) 

Now I fully admit that I used db / models / query.py as a starting point. My problem is on this line.

obj = self.model(**params)

I can get the parameters, but I have not defined self.model. I do not understand what it should be, and it is not intuitively obvious what value should be. Even looking back at query.py, I can't figure it out. Can someone explain this to me? I would really like to understand this and fix my code.

thanks

+3
3

. .

# Managers

class P4Manager(models.Manager):
  def p4_run_command(self, command):
    """Runs a basic perforce command and return the values"""
    p4 = P4.P4()
    p4.connect()
    values = p4.run(command)
    p4.disconnect()
    return self.__unify_key_values__(values)

  def __unify_key_values__(self, args):
    """Unified method to clean up the lack of standard returns from p4 api"""
    final = []
    for item in args:
      params = dict( [(k.lower(),v) for k, v in item.items()])
      results = {}
      for k, v in params.items():
        if k in ['password', ]: continue
        if k in ["access", "update"]:
          v = datetime.datetime.strptime(v, "%Y/%m/%d %H:%M:%S") 
        results[k]=v
      final.append(results)
    return final

  def __get_or_retrieve_singleton__(self, **kwargs):
    """This little sucker will retrieve a key if the server doesn't have it.
       In short this will go out to a perforce server and attempt to get a
       key if it doesn't exist.    
    """
    assert len(kwargs.keys())==2, \
            'get_or_retrieve() must be passed at one keyword argument'
    callback = kwargs.pop('callback', None)
    try:      
      return self.get(**kwargs), False
    except self.model.DoesNotExist:
      params = self.p4_run_command((kwargs.keys()[0], "-o", kwargs.values()))
      if callback:
        params = callback(*params)
      obj = self.model(**params)
      sid = transaction.savepoint()
      obj.save(force_insert=True)
      transaction.savepoint_commit(sid)
      return obj, True
    except IntegrityError, e:
      transaction.savepoint_rollback(sid)
      try:
        return self.get(**kwargs), False
      except self.model.DoesNotExist:
        raise e

class P4UserManager(P4Manager):
  """
  A Generic User Manager which adds a retrieve functionality
  """
  def get_or_retrieve(self, user):
    kwargs = { 'callback' : self.__userProcess__ ,
               'user': user }
    return self.__get_or_retrieve_singleton__(**kwargs)

  def __userProcess__(self, *args):
    args = args[0]
    if not args.has_key('access'):
      raise self.model.DoesNotExist()
    return args

# Models

class P4User(models.Model):
  """This simply expands out 'p4 users' """
  user      = models.CharField(max_length=100, primary_key=True)
  fullname  = models.CharField(max_length=256)
  email     = models.EmailField()
  access    = models.DateField(auto_now_add=True)
  update    = models.DateField(auto_now_add=True)
  objects   = P4UserManager()

  def __unicode__(self):
    return str(self.user) 

,

+4

get_or_create - Manager, model.objects - , model. , , .

. self.model - - . ,

obj = P4User(**params)

, .

+6

self self.model.

, , - Queryset. self.model - , . classmethod .

0
source

Source: https://habr.com/ru/post/1715577/


All Articles