рдЧреНрд░рд╛рдлреАрди-рдкрд╛рдпрдерди рдХреЗ рд╕рд╛рде рд░реЛрдорд╛рдВрдЪ рдХрд╛ рд╡рд░реНрд╖

рдЧреНрд░рд╛рдлреАрди-рдкрд╛рдпрдерди рдХреЗ рд╕рд╛рде рд░реЛрдорд╛рдВрдЪ рдХрд╛ рд╡рд░реНрд╖


рдЫрд╡рд┐


рд╣рд╛рдп рд╕рдм, рдореИрдВ рдПрдХ рдЕрдЬрдЧрд░ рдбреЗрд╡рд▓рдкрд░ рд╣реВрдБред рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ рдореИрдВрдиреЗ рдЧреНрд░рд╛рдлреАрди-рдкрд╛рдЗрдерди + рдбреАрдЬреЗрдВрдЧреЛ рдУрдЖрд░рдПрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕ рджреМрд░рд╛рди рдореИрдВрдиреЗ рдЧреНрд░рд╛рдлреАрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдХрд░рдг рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рдирддреАрдЬрддрди, рдореБрдЭреЗ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ graphene-framework рдХреЛрдб рдЖрдзрд╛рд░ рдФрд░ рдХреБрдЫ рдирд┐рдпрдореЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдорд┐рд▓рд╛, рдЬрд┐рд╕реЗ рдореИрдВ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред


рдЫрд╡рд┐


рдЧреНрд░рд╛рдлреАрди-рдкрд╛рдпрдерди рдХреНрдпрд╛ рд╣реИ?


рдЧреНрд░рд╛рдлреАрди-python.org рдХреЗ рдЕрдиреБрд╕рд╛рд░, рддрдм:


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

рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдПрдХ рд╕рд░рд▓ рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░реНрд╕ рдХреЗ рдЬреАрд╡рди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред


рд╣рд╛рдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЧреНрд░рд╛рдлреАрди рд╕рд░рд▓ рдФрд░ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рдмрдбрд╝реЗ рдФрд░ рддреЗрдЬреА рд╕реЗ рдмрдврд╝рддреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИред рд▓рдШреБ рдкреНрд░рд▓реЗрдЦрди (рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ - рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреНрд░рд┐рдпрд╛ рд╣реИ), рд╕рд╛рде рд╣реА рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХреЛрдВ рдХреА рдХрдореА рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЖрдкрдХреЗ рдЕрдЧрд▓реЗ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рдмрдирд╛рддреА рд╣реИред


рд╡реИрд╕реЗ рднреА, рдореИрдВрдиреЗ рдЗрд╕реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдФрд░ рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рднрд╛рдЧ рд▓рд┐рдпрд╛, рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЙрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛ рд╣рд▓ рдХрд░ рджрд┐рдпрд╛ (рдЧреНрд░реЗрдлреАрди рдХреА рд╕рдореГрджреНрдз рдЕрдиреИрдЪреНрдЫрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж)ред рдореЗрд░реЗ рдХреБрдЫ рд╕рдорд╛рдзрд╛рди рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рд╣реИрдВ рдФрд░ рдореЗрд░реА рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рдмрд┐рдирд╛, рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЙрдирдореЗрдВ рд╕реЗ рдмрд╛рдХреА рдХреЛ рдЕрднреА рднреА рдХреБрдЫ рдХреЛрдб рдмреЗрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдпрд╣ рд▓реЗрдЦ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рддрд░рд╣ рд╕реЗ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдорд╛рд░реНрдЧ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рдФрд░ рдореЗрд░реА рдкрд╕рдВрдж рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдФрдЪрд┐рддреНрдп рдХреЗ рд╕рд╛рде рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХреА рдЧрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рдореИрдВрдиреЗ рдореНрдпреВрдЯреЗрд╢рди рдФрд░ рдЙрдирд╕реЗ рдЬреБрдбрд╝реА рдЪреАрдЬреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ред


рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХрд┐рд╕реА рднреА рд╕рд╛рд░реНрдердХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЖрд▓реЛрдЪрдирд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реВрдВрдЧрд╛!


рдиреЛрдЯ: рд▓реЗрдЦ рдХреЛ рдкрдврд╝рдирд╛ рдЬрд╛рд░реА рд░рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рджреГрдврд╝рддрд╛ рд╕реЗ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдкрд░рд┐рдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЧреНрд░рд╛рдлрдХреЙрдХ рдХреНрдпрд╛ рд╣реИред




рдореНрдпреВрдЯреЗрд╢рди


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

рдореНрдпреВрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:


 class UpdatePostMutation(graphene.Mutation): class Arguments: post_id = graphene.ID(required=True) title = graphene.String(required=True) content = graphene.String(required=True) image_urls = graphene.List(graphene.String, required=False) allow_comments = graphene.Boolean(required=True) contact_email = graphene.String(required=True) ok = graphene.Boolean(required=True) errors = graphene.List(graphene.String, required=True) def mutate(_, info, post_id, title, content, image_urls, allow_comments, contact_email): errors = [] try: post = get_post_by_id(post_id) except PostNotFound: return UpdatePostMutation(ok=False, errors=['post_not_found']) if not info.context.user.is_authenticated: errors.append('not_authenticated') if len(title) < TITLE_MIN_LENGTH: errors.append('title_too_short') if not is_email(contact_email): errors.append('contact_email_not_valid') if post.owner != info.context.user: errors.append('not_post_owner') if Post.objects.filter(title=title).exists(): errors.append('title_already_taken') if not errors: post = Utils.update_post(post, title, content, image_urls, allow_comments, contact_email) return UpdatePostMutation(ok=bool(errors), errors=errors) 

UpdatePostMutation рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреЛрд╕реНрдЯ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рд╢рд░реНрддреЛрдВ рдХреЗ рдкреВрд░рд╛ рди рд╣реЛрдиреЗ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред


рдХреЗрд╡рд▓ рдЗрд╕ рдХреЛрдб рдХреЛ рджреЗрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЗрд╕рдХреА рдЧреИрд░-рд╡реНрдпрд╛рдкрдХрддрд╛ рдФрд░ рдЕрд╕рдорд░реНрдерддрд╛ рдХреЗ рдХрд╛рд░рдг рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ:


  1. mutate рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рддрд░реНрдХ, рдЬрд┐рдирдХреА рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝ рд╕рдХрддреА рд╣реИ, рднрд▓реЗ рд╣реА рд╣рдо рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реЛрдВред
  2. рдХреНрд▓рд╛рдЗрдВрдЯ рдкрдХреНрд╖ рдкрд░ рд╕рдорд╛рди рджрд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореНрдпреВрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ errors рдФрд░ ok рд▓реМрдЯрдирд╛ рдЪрд╛рд╣рд┐рдП, рддрд╛рдХрд┐ рдЙрдирдХреА рд╕реНрдерд┐рддрд┐ рдФрд░ рдпрд╣ рд╕рдордЭрдирд╛ рд╣рдореЗрд╢рд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗред
  3. mutate рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЦреЛрдЬреЗрдВ рдФрд░ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдореНрдпреВрдЯреЗрд╢рди рдлрд╝рдВрдХреНрд╢рди рдЙрдкрд╡рд╛рд╕ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  4. рдПрдХ рдореНрдпреВрдЯреЗрд╢рди рдореЗрдВ рдЕрдиреБрдорддрд┐рдпреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ред рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рдирд╣реАрдВ рд╣реИ (рдХреБрдЫ рдкреЛрд╕реНрдЯ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ) рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  5. рдПрдХ рдмреЗрдХрд╛рд░ рдкрд╣рд▓рд╛ рддрд░реНрдХ (рдПрдХ рдЬрдбрд╝ рдЬреЛ рд╣рдореЗрд╢рд╛ рд╢реАрд░реНрд╖ рд╕реНрддрд░ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП None , рдЬреЛ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рд╣реИ)ред
  6. рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╕реЗрдЯ: рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╕реНрд░реЛрдд рдХреЛрдб рдпрд╛ рдкреНрд░рд▓реЗрдЦрди рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдирд╣реАрдВ рдкрддрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рдХреНрдпрд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдпреЛрдЬрдирд╛ рдореЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред
  7. рдХрдИ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рддреНрд░реБрдЯрд┐ рдЬрд╛рдВрдЪ рд╣реИрдВ рдЬреЛ рд╕реАрдзреЗ mutate рдкрджреНрдзрддрд┐ рдореЗрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪреЗрдХ рдХреЗ рдмрдЬрд╛рдп рдбреЗрдЯрд╛ рдХреЛ mutate рд╢рд╛рдорд┐рд▓ рд╣реИред рдЖрджрд░реНрд╢ mutate рдореЗрдВ рдПрдХ рдкрдВрдХреНрддрд┐ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП - рдкреЛрд╕реНрдЯ рд╕рдВрдкрд╛рджрди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ред

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдФрд░ рдЗрдирдкреБрдЯ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдЬреИрд╕реЗ рддреГрддреАрдп-рдкрдХреНрд╖ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп, mutate рдХреЛ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ред рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣реИ:


  def mutate(post, info, input): post = Utils.update_post(post, **input) return UpdatePostMutation(post=post) 

рдЕрдм рдКрдкрд░ рдХреЗ рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдЧреМрд░ рдХрд░рддреЗ рд╣реИрдВред




рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░


email рдлрд╝реАрд▓реНрдб рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдпрд╣ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рд╛рд░реВрдк рдХреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ ред рд╣рд░ рдмрд╛рд░ рдПрдкреАрдЖрдИ рдХреЛ рдПрдХ рдИрдореЗрд▓ рдорд┐рд▓рддрд╛ рд╣реИ, рдЙрд╕реЗ рдЗрд╕рдХреА рд╢реБрджреНрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рддреЛ рдПрдХ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рд╣реЛрдЧрд╛ред


 class Email(graphene.String): # ... 

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИред




рдЗрдирдкреБрдЯ рдкреНрд░рдХрд╛рд░


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


 class UpdatePostInput(graphene.InputObjectType): title = graphene.String(required=True) content = graphene.String(required=True) image_urls = graphene.List(graphene.String, required=False) allow_comments = graphene.Boolean(required=True) contact_email = graphene.String(required=True) 

рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:


 mutation( $post_id: ID!, $title: String!, $content: String!, $image_urls: String!, $allow_comments: Boolean!, $contact_email: Email! ) { updatePost( post_id: $post_id, title: $title, content: $content, image_urls: $image_urls, allow_comments: $allow_comments, contact_email: $contact_email, ) { ok } } 

рдХреЗ рдмрд╛рдж:


 mutation($id: ID!, $input: UpdatePostInput!) { updatePost(id: $id, input: $input) { ok } } 

рдореНрдпреВрдЯреЗрд╢рди рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИ:


 class UpdatePostMutation(graphene.Mutation): class Arguments: input = UpdatePostInput(required=True) id = graphene.ID(required=True) ok = graphene.Boolean(required=True) errors = graphene.List(graphene.String, required=True) def mutate(_, info, input, id): # ... if not errors: post = Utils.update_post(post, **input.__dict__) return UpdatePostMutation(errors=errors) 



рдЖрдзрд╛рд░ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рд╡рд░реНрдЧ


рдЬреИрд╕рд╛ рдХрд┐ рдкреИрд░рд╛рдЧреНрд░рд╛рдл 2 рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдореНрдпреВрдЯреЗрд╢рди рдореЗрдВ errors рдФрд░ ok рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдЙрдирдХреА рд╕реНрдерд┐рддрд┐ рдФрд░ рдХреНрдпрд╛ рдХрд╛рд░рдг рд╣реЛ, рдЗрд╕реЗ рд╣рдореЗрд╢рд╛ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХреЗ ред рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рд╣рдо рдПрдХ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдмрдирд╛рддреЗ рд╣реИрдВ:


 class MutationPayload(graphene.ObjectType): ok = graphene.Boolean(required=True) errors = graphene.List(graphene.String, required=True) query = graphene.Field('main.schema.Query', required=True) def resolve_ok(self, info): return len(self.errors or []) == 0 def resolve_errors(self, info): return self.errors or [] def resolve_query(self, info): return {} 

рдХреБрдЫ рдиреЛрдЯ:


  • resolve_ok рд╡рд┐рдзрд┐ resolve_ok , рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╕реНрд╡рдпрдВ ok рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
  • query рдлрд╝реАрд▓реНрдб рд░реВрдЯ Query , рдЬреЛ рдЖрдкрдХреЛ рдореНрдпреВрдЯреЗрд╢рди рдЕрдиреБрд░реЛрдз рдХреЗ рдЕрдВрджрд░ рд╕реАрдзреЗ рдбреЗрдЯрд╛ рдХреНрд╡реЗрд░реА рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдореНрдпреВрдЯреЗрд╢рди рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдбреЗрдЯрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)ред
     mutation($id: ID!, $input: PostUpdateInput!) { updatePost(id: $id, input: $input) { ok query { profile { totalPosts } } } } 

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


рдмреЗрд╕ рдореНрдпреВрдЯреЗрд╢рди рдХреНрд▓рд╛рд╕ рдХреЗ рд╕рд╛рде, рдХреЛрдб рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ:


 class UpdatePostMutation(MutationPayload, graphene.Mutation): class Arguments: input = UpdatePostInput(required=True) id = graphene.ID(required=True) def mutate(_, info, input, id): # ... 



рд░реВрдЯ рдореНрдпреВрдЯреЗрд╢рди


рд╣рдорд╛рд░рд╛ рдореНрдпреВрдЯреЗрд╢рди рдЕрдиреБрд░реЛрдз рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 mutation($id: ID!, $input: PostUpdateInput!) { updatePost(id: $id, input: $input) { ok } } 

рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рджрд╛рдпрд░реЗ рдореЗрдВ рд╕рднреА рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдБ рдХреБрдЫ рдХрд╛рд░рдг рд╣реИрдВ:


  1. рдореНрдпреВрдЯреЗрд╢рди рдХреА рдмрдврд╝рддреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде, рдЖрдкрдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдвреВрдВрдврдирд╛ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
  2. рдПрдХ рдирд╛рдо рд╕реНрдерд╛рди рдХреЗ рдХрд╛рд░рдг, рдореНрдпреВрдЯреЗрд╢рди рдХреЗ рдирд╛рдо рдкрд░ "рдЗрд╕рдХреЗ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо" рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП update Post ред
  3. рдЖрдкрдХреЛ рдореНрдпреВрдЯреЗрд╢рди рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ id рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдореИрдВ рд░реВрдЯ рдореНрдпреВрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВред рдЙрдирдХрд╛ рд▓рдХреНрд╖реНрдп рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдХреЛрдк рдореЗрдВ рдмрджрд▓рдХрд░ рдФрд░ рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рдПрдХреНрд╕реЗрд╕ рд╕реЗ рддрд░реНрдХ рд╕реЗ рдореБрдХреНрдд рдХрд░рдирд╛ рдФрд░ рдЙрди рддрдХ рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдирд╛ рд╣реИред


рдирдпрд╛ рдЕрдиреБрд░реЛрдз рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 mutation($id: ID!, $input: PostUpdateInput!) { post(id: $id) { update(input: $input) { ok } } } 

рдЕрдиреБрд░реЛрдз рддрд░реНрдХ рд╕рдорд╛рди рд░рд╣рддреЗ рд╣реИрдВред рдЕрдм рдкрд░рд┐рд╡рд░реНрддрди рдлрд╝рдВрдХреНрд╢рди рдХреЛ post рдЕрдВрджрд░ "рдХреЙрд▓" рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:


  1. рдпрджрд┐ id post рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рдпрд╣ {} рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддреА рд╣реИ рдпрд╣ рдЖрдкрдХреЛ рднреАрддрд░ рдореНрдпреВрдЯреЗрд╢рди рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрди рдореНрдпреВрдЯреЗрд╢рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд░реВрдЯ рддрддреНрд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП)ред
  2. рдпрджрд┐ id рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рддрддреНрд╡ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  3. рдпрджрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рддреЛ None рд╡рд╛рдкрд╕ None , рдФрд░ рдпрд╣ рдЕрдиреБрд░реЛрдз рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, рдореНрдпреВрдЯреЗрд╢рди рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
  4. рдпрджрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ рд╣реЗрд░рдлреЗрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред
  5. рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ рдЕрдзрд┐рдХрд╛рд░ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ None рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдиреБрд░реЛрдз рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдореНрдпреВрдЯреЗрд╢рди рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
  6. рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдзрд┐рдХрд╛рд░ рд╣реИрдВ, рддреЛ рдкрд╛рдпрд╛ рдЧрдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рд╣реИ рдФрд░ рдореНрдпреВрдЯреЗрд╢рди рдЗрд╕реЗ рд░реВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ - рдкрд╣рд▓рд╛ рддрд░реНрдХред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИ:


 class UpdatePostMutation(MutationPayload, graphene.Mutation): class Arguments: input = UpdatePostInput() def mutate(post, info, input): if post is None: return None errors = [] if not info.context.user.is_authenticated: errors.append('not_authenticated') if len(title) < TITLE_MIN_LENGTH: errors.append('title_too_short') if Post.objects.filter(title=title).exists(): errors.append('title_already_taken') if not errors: post = Utils.update_post(post, **input.__dict__) return UpdatePostMutation(errors=errors) 

  • рдореНрдпреВрдЯреЗрд╢рди рдХреА рдЬрдбрд╝ - рдкрд╣рд▓рд╛ рддрд░реНрдХ - рдЕрдм рдЯрд╛рдЗрдк Post рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдКрдкрд░ рдореНрдпреВрдЯреЗрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдЪреЗрдХ рд░реВрдЯ рдореНрдпреВрдЯреЗрд╢рди рдХреЛрдб рдореЗрдВ рдЪрд▓рд╛ рдЧрдпрд╛ред

рд░реВрдЯ рдореНрдпреВрдЯреЗрд╢рди рдХреЛрдб:


 class PostMutationRoot(MutationRoot): class Meta: model = Post has_permission = lambda post, user: post.owner == user update = UpdatePostMutation.Field() 



рддреНрд░реБрдЯрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕


рдЕрдиреБрдорд╛рдирд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдореЗрдВ рдкрд░рд┐рд▓рдХреНрд╖рд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


  • рдЪреВрдВрдХрд┐ рдореНрдпреВрдЯреЗрд╢рди рдХрдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
  • рдЪреВрдВрдХрд┐ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ Union рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдЕрд╕реНрддрд┐рддреНрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  • рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рдорд╛рди рдмрдиреЗ рд░рд╣рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЖрдЗрдП рдЗрд╕реЗ ErrorInterface рдХрд╣рддреЗ рд╣реИрдВред рдЗрд╕реЗ рджреЛ рдлрд╝реАрд▓реНрдбреНрд╕ рджреЗрдВ: ok рдФрд░ message ред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдЯрд╛рдЗрдк [SomeMutationErrorsUnion]! рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП [SomeMutationErrorsUnion]! ред SomeMutationErrorsUnion рд╕рднреА рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ SomeMutationErrorsUnion рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред


рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:


 class NotAuthenticated(graphene.ObjectType): message = graphene.String(required=True, default_value='not_authenticated') class Meta: interfaces = [ErrorInterface, ] class TitleTooShort(graphene.ObjectType): message = graphene.String(required=True, default_value='title_too_short') class Meta: interfaces = [ErrorInterface, ] class TitleAlreadyTaken(graphene.ObjectType): message = graphene.String(required=True, default_value='title_already_taken') class Meta: interfaces = [ErrorInterface, ] class UpdatePostMutationErrors(graphene.Union): class Meta: types = [NotAuthenticated, TitleIsTooShort, TitleAlreadyTaken, ] 

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


 class PostErrors(metaclass=ErrorMetaclass): errors = [ 'not_authenticated', 'title_too_short', 'title_already_taken', ] class UpdatePostMutationErrors(graphene.Union): class Meta: types = [PostErrors.not_authenticated, PostErrors.title_too_short, PostErrors.title_already_taken, ] 

рдореНрдпреВрдЯреЗрд╢рди рдореЗрдВ рд▓реМрдЯреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдЬреЛрдбрд╝реЗрдВ:


 class UpdatePostMutation(MutationPayload, graphene.Mutation): class Arguments: input = UpdatePostInput() errors = graphene.List(UpdatePostMutationErrors, required=True) def mutate(post, info, input): # ... 



рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░реЗрдВ


рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ mutate рдкрджреНрдзрддрд┐ рдХреЛ рдбреЗрдЯрд╛ рдХреЛ рдореНрдпреВрдЯ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЙрдирдХреЗ рдХреЛрдб рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реБрдП, рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:


 class UpdatePostMutation(DefaultMutation): class Arguments: input = UpdatePostInput() class Meta: root_required = True authentication_required = True #   ,    True   # An iterable of tuples (error_class, checker) checks = [ ( PostErrors.title_too_short, lambda post, input: len(input.title) < TITLE_MIN_LENGTH ), ( PostErrors.title_already_taken, lambda post, input: Post.objects.filter(title=input.title).exists() ), ] def mutate(post, info, input): post = Utils.update_post(post, **input.__dict__) return UpdatePostMutation() 

mutate рдлрд╝рдВрдХреНрд╢рди рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рддреНрдпреЗрдХ рдЪреЗрдХрд░ ( checks рд╕рд░рдгреА рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХрд╛ рджреВрд╕рд░рд╛ рддрддреНрд╡) рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ True рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рддреНрд░реБрдЯрд┐ рдкрд╛рдИ рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рдорд┐рд▓рддреА рд╣реИ, рддреЛ mutate рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред


рдореИрдВ рд╕рдордЭрд╛рдКрдВрдЧрд╛:


  • рдЪреЗрдХ рдлрд╝рдВрдХреНрд╢рдВрд╕, mutate рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреА рддрд░рд╣ рд╣реА рддрд░реНрдХ рджреЗрддреЗ рд╣реИрдВред
  • рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ, рддреЛ рд╕рддреНрдпрд╛рдкрди рдХрд╛рд░реНрдп True рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  • рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рдЪреЗрдХ рдФрд░ рд░реВрдЯ рддрддреНрд╡ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИ рдФрд░ Meta рдлреНрд▓реИрдЧ рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рд╣реИрдВред
  • True authentication_required рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдЬрд╛рдБрдЪ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
  • root_required " root is not None " рдЪреЗрдХ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
  • UpdatePostMutationErrors рдЕрдм рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред checks рд╕рд░рдгреА рдХреЗ рддреНрд░реБрдЯрд┐ рд╡рд░реНрдЧреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлреНрд▓рд╛рдИ рдкрд░ рд╕рдВрднрд╛рд╡рд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдШ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред



рдЬреЗрдирд░рд┐рдХ


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


рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдЯрд╛рд░реНрдЯрд░ рдХрд┐рдЯ рднреА рд╣реИ рдЬреЛ рдХреЛрдб рдХреЛ рдЫреЛрдЯрд╛ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЬреАрд╡рди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред
рдиреЛрдЯ: рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЬреЗрдиреЗрд░рд┐рдХ рдХреЛрдб django ORM рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ


CreateMutation


model рдпрд╛ create_function рдПрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, create_function рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 model._default_manager.create(**data, owner=user) 

рдпрд╣ рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдордд рднреВрд▓реЛ рдХрд┐ рдЧреНрд░реЗрдлреЗрд▓ рдореЗрдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рд╣реИ, рд╕рд╛рде рд╣реА рдореНрдпреВрдЯреЗрд╢рди рдореЗрдВ рдЪреЗрдХ рднреА рд╣реИред


рдпрд╣ рдПрдХ post_mutate рд╡рд┐рдзрд┐ рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде post_mutate рдмрд╛рдж рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ( post_mutate (instance_created, user) , рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


UpdateMutation


рдЖрдкрдХреЛ update_function рд╕реЗрдЯ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ:


 def default_update_function(instance, user=None, **data): instance.__dict__.update(data) instance.save() return instance 

root_required рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ True рд╣реИред


рдпрд╣ рдПрдХ post_mutate рд╡рд┐рдзрд┐ рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ update_function рдмрд╛рдж рддрд░реНрдХреЛрдВ (instance_updated, user) update_function (instance_updated, user) рд╕рд╛рде рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рдФрд░ рдпрд╣реА рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП!


рдЕрдВрддрд┐рдо рдХреЛрдб:


 class UpdatePostMutation(UpdateMutation): class Arguments: input = UpdatePostInput() class Meta: checks = [ ( PostErrors.title_too_short, lambda post, input: len(input.title) < TITLE_MIN_LENGTH ), ( PostErrors.title_already_taken, lambda post, input: Post.objects.filter(title=input.title).exists() ), ] 

DeleteMutation


рдЖрдкрдХреЛ delete_function рд╕реЗрдЯ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ:


 def default_delete_function(instance, user=None, **data): instance.delete() 



рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рд▓реЗрдЦ рдХреЗрд╡рд▓ рдПрдХ рдкрд╣рд▓реВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдпрд╣ рд╕рдмрд╕реЗ рдЬрдЯрд┐рд▓ рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рд░рд┐рдЬрд╝реЙрд▓реНрд╡рд░ рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЧреНрд░рд╛рдлреАрди-рдкрд╛рдпрдерди рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдЪреАрдЬреЗрдВ рд╣реИрдВред


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


рд╕реНрд░реЛрдд рдХреЛрдб рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

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


All Articles