рдХрд┐рд╕рдиреЗ рдмрдирд╛рдпрд╛, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ django рдореЗрдВ рдЕрдкрдиреЗ рдПрдореНрдмреЗрдбреЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЕрдкрдбреЗрдЯ рдпрд╛ рд▓рд┐рдЦрд╛ рд╣реИ

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, django рдПрдХ рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдФрд░ рд▓рдЪреАрд▓рд╛ рдврд╛рдВрдЪрд╛ рд╣реИред рдЙрд╕рдХреЗ рд▓рд┐рдП рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдП рдЧрдП рд╣реИрдВ, рд╕рд╛рде рд╣реА рдХреБрдЫ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдФрд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рднреА рд╣реИрдВред рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдкрд░реНрдпрд╛рдкреНрдд рдФрд░ рдиреАрд░рд╕ рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рднреА рдПрдореНрдмреЗрдбреЗрдб рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдХрд╛рд░реНрдп


рдпрд╣ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдореЙрдбрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рдХрд┐рд╕рдиреЗ рдмрдирд╛рдпрд╛ рдФрд░ / рдпрд╛ рдХрд┐рд╕рдиреЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ред

рд╡рд┐рдЪрд╛рд░


рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░реЗрдВ рддрд╛рдХрд┐ рд╕рдорд╛рдзрд╛рди рдХрд┐рд╕реА рднреА рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

рдирд┐рд░реНрдгрдп


рдЖрджрд░реНрд╢

рдЪреВрдВрдХрд┐ рд╣рдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рднрд╡рд┐рд╖реНрдп рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕ рдореЙрдбрд▓ рдореЗрдВ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдорд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдЬреЛрдбрд╝рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИред рдорд┐рдХреНрд╕рд┐рди рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореБрдЦреНрдп рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реЛрддреА рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпреЗ create_by, updated_by рдлрд╝реАрд▓реНрдб рд╣реЛрдВрдЧреЗред

from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ class CreatedByMixin(models.Model): created_by = models.ForeignKey(User, verbose_name=_('Created by'), related_name='%(class)s_created_items', ) class Meta: abstract=True class UpdatedByMixin(models.Model): updated_by = models.ForeignKey(User, verbose_name=_('Updated by'), related_name='%(class)s_updated_items', ) class Meta: abstract = True class CreatedUpdatedByMixin(CreatedByMixin, UpdatedByMixin): class Meta: abstract = True 


рд╣рдордиреЗ рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рддреАрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд░реНрдЧ рдмрдирд╛рдП рд╣реИрдВ: рдЬрдм рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╣реА рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕рдиреЗ рдмрдирд╛рдпрд╛, рдЬрдм рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рд╡рд╣реА рд╣реИ рдЬреЛ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЬрдм рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕рдиреЗ рдмрдирд╛рдпрд╛ рдФрд░ рдХрд┐рд╕рдиреЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ред
рдЕрдм рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХрд┐рд╕рдиреЗ рдмрдирд╛рдпрд╛ рдФрд░ рдХрд┐рд╕рдиреЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛, рдЖрдк рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдореЙрдбрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:



 from django.db import models from whovedonethis import models as who_models class TestCreatedUpdated(who_models.CreatedUpdatedByMixin): value = models.CharField('Value', max_length=255) 


рдмрдЪрдд рд░рд┐рдХреЙрд░реНрдб

рдЕрдм рдореЙрдбрд▓ рдореЗрдВ рдлрд╝реАрд▓реНрдб рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХреИрд╕реЗ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЬрд╛рдП рдЬрд┐рд╕рдиреЗ рдЗрд╕реЗ рдмрдирд╛рдпрд╛ рдерд╛, рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ред рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдИ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ:



рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рддрд░реАрдХрд╛ рд╕рдВрдХреЗрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХреБрдЫ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╛ рд╕рдорд╛рдзрд╛рди рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдирд╣реАрдВ рд╣реИред

рд╕рд┐рдЧреНрдирд▓ рдПрдХ рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде django рдЖрдкрдХреЛ рд╕рд┐рд╕реНрдЯрдо рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ (рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рдиреЗ рдпрд╛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ:


рдХреИрд╕реЗ рдкрддрд╛ рдХрд░реЗрдВ рдХрд┐ рдХрд┐рд╕рдиреЗ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрдирд╛рдИ / рдЕрдкрдбреЗрдЯ рдХреА?


рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЖрдорддреМрд░ рдкрд░ рдЕрдиреБрд░реЛрдз рдЪрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рддреА рд╣реИ, рдЬреЛ рдкреВрд░реНрд╡_ рд╕рд┐рдЧреНрдирд▓ рдХреЗ рджрд╛рдпрд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЖрддреА рд╣реИред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд┐рдВрдЧрд▓рдЯрди рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╣рдорд╛рд░реЗ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

 class Singleton(type): ''' Singleton pattern requires for LoggedInUser class ''' def __init__(cls, name, bases, dicts): cls.instance = None def __call__(cls, *args, **kwargs): if cls.instance is None: cls.instance = super(Singleton, cls).__call__(*args, **kwargs) return cls.instance class NotLoggedInUserException(Exception): ''' ''' def __init__(self, val='No users have been logged in'): self.val = val super(NotLoggedInUser, self).__init__() def __str__(self): return self.val class LoggedInUser(object): __metaclass__ = Singleton user = None def set_user(self, request): if request.user.is_authenticated(): self.user = request.user @property def current_user(self): ''' Return current user or raise Exception ''' if self.user is None: raise NotLoggedInUserException() return self.user @property def have_user(self): return not user is None from whovedonethis.loggedinuser import LoggedInUser class LoggedInUserMiddleware(object): ''' Insert this middleware after django.contrib.auth.middleware.AuthenticationMiddleware ''' def process_request(self, request): ''' Returned None for continue request ''' logged_in_user = LoggedInUser() logged_in_user.set_user(request) return None 


рд╕рдВрдХреЗрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХреНрдпрд╛ рд╣реИред

рдЪреВрдВрдХрд┐ рд╕рд┐рдЧреНрдирд▓ рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдбреЗрдХреЛрд░реЗрдЯрд░ рдирд╣реАрдВ рд▓рд┐рдЦреЗрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд╕рдВрдХреЗрддреЛрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓ рджреЗрдЧрд╛, рд╣рдореЗрдВ рдЙрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЬреЛрдбрд╝ рд░рд╣рд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдЗрдП рдПрдХ рдЪреЗрдХ рдЬреЛрдбрд╝реЗрдВ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХрд┐рд╕ рдлрд╝реАрд▓реНрдб рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдпрджрд┐ рдореЙрдбрд▓ рдореЗрдВ 'create_by_field / updated_by_field' рдлрд╝реАрд▓реНрдб рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдорд╛рдирдХ рдлрд╝реАрд▓реНрдб рдореЗрдВ рдЕрдиреНрдпрдерд╛ рдЕрдиреНрдпрдерд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдлрд╝реАрд▓реНрдб рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВрдЧреЗред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП, рди рдХрд┐ рдЗрд╕рдХреА рд╕рдВрд░рдЪрдирд╛, рд╣рдо рдлрдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдлрдВрдХреНрд╢рдВрд╕ рд╕реЗ рдХрд░реЗрдВрдЧреЗред

 from functools import wraps from whovedonethis.loggedinuser import LoggedInUser def add_created_user(f): ''' Decorate pre_save signal for adding created user ''' @wraps(f) def wrapper(sender, instance, **kwargs): if not instance.id: created_by_attr = getattr(instance, "created_by_field", "created_by" ) setattr(instance, created_by_attr, LoggedInUser().current_user) return f(sender, instance, **kwargs) return wrapper def add_updated_user(f): ''' Decorate pre_save signal for adding created user ''' @wraps(f) def wrapper(sender, instance, **kwargs): updated_by_attr = getattr(instance, "updated_by_field", "updated_by" ) setattr(instance, updated_by_attr, LoggedInUser().current_user) return f(sender, instance, **kwargs) return wrapper add_created_and_updated_user = lambda x: add_created_user(add_updated_user(x)) add_created_and_updated_user.__doc__ =\ ''' Decorate pre_save signal for adding created and updated user ''' 


рдкрд░рд┐рдгрд╛рдо


рдЦреИрд░, рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рд╣реИред рдЕрдм рдпрд╣ рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд╛рде рд░рдЦрдиреЗ рдФрд░ рд╣рдорд╛рд░реЗ рдПрдореНрдмреЗрдбреЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред

рднрдВрдбрд╛рд░:


рдкреБрдирд╢реНрдЪ

рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рддреНрд░реБрдЯрд┐ рд╕рдВрдХреЗрддреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╡рд░реНрддрдиреА рдФрд░ рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрди рдореЗрдВред

рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рд▓реЗрдЦрди PyCon 2011 рдХреЗ рд╕рд╛рде рдПрдХ рдХреЛрд░реА рдУрд░реНрдбреЗрдЯ рд╡рд╛рд░реНрддрд╛ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдерд╛ред

рдпреБрдкреАрдбреАред
рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рд╕рд┐рдЧреНрдирд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:

 from django.db.models.signals import pre_save from django.dispatch import receiver from whovedonethis import decorator from testlib.models import TestCreated @receiver(pre_save, sender=TestCreated) @decorator.add_created_user def pre_save_testcreated_handler(sender, instance, **kwargs): pass 

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


All Articles