Настольная игра Дженга: обзор, правила, рекомендации
Популярная настольная игра Дженга будет интересна детям любого возраста, в нее можно играть, как одному, так и большой компанией. Она развивает ловкость, мелкую моторику рук, воображение, а из блоков можно строить самые разнообразные конструкции. Легендарная Дженга – классика настольных игр, она во всем мире пользуется огромной популярностью. В коробке определенное количество деревянных брусочков. Магазин «Тотоша» предлагает игру Дженга для детей любого возраста по доступной стоимости.
Дженга: главные преимущества
Гигантская игра деревянная башня Дженга подходит для большой компании друзей, это увлекательный и захватывающий процесс, который никого не оставит равнодушным. К основным преимуществам Дженга относятся:
- экологическая безопасность;
- длительный срок службы;
- надежность и прочность брусочков;
- отсутствие языкового барьера;
- гладкость поверхности, что гарантирует безопасность;
- большой выбор наборов в зависимости от количества брусков.
Дженга – это оптимальный выбор для подарка на день рождения ребенку, который, несомненно, оценит креативный подход и оригинальность.
Дженга: простые правила
Правила игры Дженга простые и понятные каждому. Стоимость Дженга зависит от количества деревянных брусков в упаковке, которые применяются для построения башни. Перед тем, как начать играть, рекомендуется изучить несложные правила. Игровой процесс заключается в том, чтобы выстроить из деревянных блоков высокую башню, после чего участники поочередно вытягивают по одному брусочку из любой части постройки. Его выкладывают сверху, строя все новые этажи. Смысл заключается в том, чтобы не допустить падения конструкции. Проигравшим считается тот игрок, который извлек брусок и башня упала. Дженга затягивает в увлекательный игровой процесс, особенно нравится игра азартным игрокам. Это беспроигрышный вариант для вечеринки или празднования дня рождения, развивает мышление и логику.
Дженга: история появления игры
Популярную настольную игру Дженга придумала дизайнер из Британии более тридцати лет назад. Но в те времена вместо привычных деревянных брусков применялись элементы конструктора, который автор привезла из Ганы. На основе этой африканской игры была придумана еще одна подобная версия, которая называлась «Та-Ка-Ради». Но она не получила такой большой популярности, как Дженга. В переводе слово Дженга означает «строить», и, несмотря на оригинальность названия для европейцев, оно стало для них интересным.
Дженга: комплектация игры
В стандартном наборе игры Дженга 54 деревянных блока продолговатой формы. Каждый блок имеет тщательно отшлифованные стенки, которые не покрываются лаком или краской. Такой способ обработки позволяет повысить трение между брусками, поэтому конструкция характеризуется повышенной устойчивостью. В классической игре Дженга размеры каждого блока составляют 1,5*2,5*7,5 см, но сегодня производители предлагают большое разнообразие, учитывая желания и отзывы покупателей. Соотношение размеров сторон блоков принципиально сохраняется.
Дженга: подготовка и игровой процесс
Подготовка к игре Дженга не занимает много времени, для начала необходимо выстроить башню и тщательно выровнять ее при помощи коробки или специального уголка из пластика. В итоге получается конструкция из 18 этажей, в каждом по три блока. Элементы конструкции плотно приставляют друг к другу, а каждый новый ряд укладывается перпендикулярно предыдущему. Играть можно, как вдвоем, так и большой компанией. Доставать блоки из башни разрешается только одной рукой. Участники вытягивают бруски по очереди, спустя 10 секунд после того, как предыдущий участник положил блок сверху конструкции.
Дженга: популярные разновидности
Благодаря большой популярности классической игры Дженга, современные производители разработали подобные версии. Это могут быть игрушки для развития детей – компактные наборы из маленьких брусочков и гигантские экземпляры, которые в последнее время широко используются на открытых детских площадках и уличных праздниках. К основным «ремейкам» настольной игры Дженга относятся следующие виды:
- «Бросай и ходи»;
- «Правда или желание»;
- «Девичьи разговоры»;
- «Экстрим»;
- «Казино Лас-Вегаса»;
- «Кошмар перед Рождеством»;
- «Дженга XXL»;
- «Груда костей».
Большой выбор разновидностей позволяет легко подобрать игру на свой вкус. Интернет-магазин «Тотоша» предоставляет официальную гарантию и сертификаты качества и экологической безопасности. Например, «Дженга: бросай и ходи» сочетает в себе классический вариант башни и игровые кости. Бросая кубик по очереди, каждый участник получает индивидуальное задание: сколько блоков и откуда именно их достать (низ, середина, верх конструкции). Для тех, кто любит экстрим предлагается игра с соответствующим названием. Это не стандартный прямоугольный параллелепипед, а параллелограмм, который позволяет выстраивать причудливые и скошенные конструкции. Для девичника подойдет «Дженга: девичьи разговоры». На поверхности розовых и малиновых блоков написаны вопросы, на которые участницы по очереди отвечают, вытягивая кубики. Такая настольная игра позволяет разнообразить посиделки.
Дженга – популярная игра во всем мире!
Дженга является одной из самых популярных настольных игр во всем мире. Она представлена в большом разнообразии моделей на любой вкус. К главным плюсам можно отнести:
- экологическую безопасность и безвредность натурального дерева;
- прочность и долговечность блоков;
- отсутствие возрастных ограничений.
Дженга – это блочные конструкторы из дерева, деревянная башня растет и падает, снова растет и падает, помогает развить логику, чувство равновесия и мелкую моторику рук.
Сломай эту стену! История настольной игры Дженга
Кто не слышал про замечательную игру на ловкость и координацию под названием «Дженга» или «Башня», в которой игроки стараются как можно дольше не разрушить деревянную башню? Сейчас каждый может свободно купить эту настольную игру и трудно представить, что еще пятьдесят лет назад «Дженги» не было еще даже в планах. История ее создания — простая и правдивая, из которой можно научиться тому, как правильно создать, продать и купить хорошую и качественную игру.
По своей сути, «Дженга» — это игра, в которой побеждает самый ловкий и осторожный игрок. Правила просты: участники должны по очереди вынимать из собранной башни деревянные блоки и ставить их на верхний этаж, с каждым разом наращивая высоту сооружения. Тот игрок, от чьих действий башня рушится, считается проигравшим. Сама башня строится из 54 блоков определенного размера (впрочем, и размеры, и количество блоков могут сильно разниться от версии к версии). Согласно оригинальным правилам, игроки могут пользоваться только одной рукой, и обязаны вернуть блок на место, если потрогали его, но решили не вынимать.
Несложные правила, приятные деревянные компоненты, море веселья, доступная цена, благодаря которой игру может купить каждый — все это делает «Дженгу» крайне популярным развлечением.
«Дженгу» создала в семидесятых годах соосновательница компании «Oxford Games Ltd» Лесли Скотт. Она взяла за основу простую игру с деревянными блоками, в которую играла в детстве в городе Такоради, расположенном в западноафриканской стране Гане. Республика Гана богата на леса, и местные мастера часто создают различные поделки из древесины. Одну из таких поделок, детскую игру, и решила купить семья Скотта, положив тем самым начало истории одной из самых известных настольных игр мира. Уважение к происхождению игры видно в ее названии. Ведь само слово jenga означает «строить» на суахили, втором родном языке Лесли Скотт.
Впервые «Дженга» увидела большой свет на Лондонской Ярмарке Игрушек в 1983 году. Лесли Скотт решила, что людям будет проще купить его игру, если она будет продавать ее через собственную компанию, названную «Leslie Scott Associates». Блоки из первой версии «Дженги» были сделаны самой Лесли в мануфактуре недалеко от Бостона. Одна «Дженга» из первой партии попала даже в Музей Детства V&A.
Уже в следующем году благодаря Роберту Греблеру, брату близкого друга Лесли «Дженгу» могли купить жители Канады. А в 1985 Греблер решил купить у Лесли Скотт эксклюзивные права на издание игры «Дженга» в США и Канаде. Игра быстро приобрела популярность в этих странах и крупная компания «Hasbro», у которой всегда был нюх на популярные продукты, купила права на издание «Дженги» по всему миру.
Если верить Лесли Скотт, на сегодняшний день около пятидесяти миллионов экземпляров «Дженги» было продано по всему миру. Это означает, что миллионы человек за сорок лет решили купить почти три миллиона деревянных блоков! И по сей день десятки тысяч человек по всему миру радуются этой великолепной игре. Самая высокая «Дженга» в мире была собрана Робертом Греблером. Эта «Дженга» состояла из 402 уровней! А сколько этажей сможете построить вы?
Читайте также:
По следам Вавилона. Настольная игра Дженга
Дженга – ловкость рук
Развивающие настольные игры. Часть 2
Дженга секреты игры, как выиграть!
Многие хоть раз пробовали себя в увлекательной игре Дженга, где основным ключом к успеху являются ловкость рук и ясный ум. Популярная игра родом из 70-х, ее придумала англичанка Лесли Скотт, когда была еще маленькой. Обычно детей привлекают к игре с 5-6 лет, но по опыту, и развитая трехлетка способна понять правила.
Стандартно для игры используется 54 деревянных брусочка, реже – 48 или 60. Ширина каждой деревяшки в три раза меньше длины и два раза больше высоты. Это важно для того, чтобы построить ровную башню. Цель игры – из построенной башни по очереди достать бруски и переложить их наверх. С каждым ходом шаткость конструкции растет вверх.
Правила игры
Играть можно от 2-х человек, оптимальное количество игроков – 3-5. Для начала нужно выбрать того, что построит конструкцию. Он и будет делать первый ход. Участник выкладывает деревяшки в 18 этажей, по 3 на каждом. В первый ряд бруски укладываются параллельно, во второй – перпендикулярно и так по очереди.
По часовой стрелке участники вытягивают по одному элементу из конструкции (исключение составляют первые 2 верхних этажа) и размещают его вверху башни. В игре участвует только одна рука: придерживать, вытаскивать двумя запрещено. После каждого действия игрока необходимо подождать 10 секунд – если конструкция не падает, право хода достается следующему. Партия оканчивается, когда конструкция рушится – игрок, чей ход был в момент падения, считается проигравшим.
Дженга — секреты игрыДженга – не та игра, где везет новичкам. Однако для победы Вам потребуется не только опыт, но и внимательности, а также везение. Существует несколько советов, которые помогут Вам выйти из игры победителем:
- помните, что свободные элементы не обязательно расположены наверху или по краям. Не забывайте проверять середину башни;
- боковые бруски безопаснее выковыривать, а центральные – выталкивать;
- чем плавнее и мягче будут Ваши движения, тем больше шансов, что конструкция не рухнет. Резкие движения опасны разрушением;
- когда конструкция начинает наклоняться, осмотрите противоположную сторону – там появятся несколько свободных брусков;
- не забывайте, что Ваша цель – выиграть любой ценой, поэтому подставляйте противников, рискуйте и усугубляйте наклон башни. Правда, прежде подумайте, не завалится ли конструкция на Вашем ходе.
Эти небольшие хитрости помогут Вам стать победителем. В дополнении отметим, что эта увлекательная игра рекомендуется специалистами для домашних коллекций настольных игр, так как положительно влияет на мозг и мелкую моторику.
Интересно:
ДЖЕНГА — знаете ли вы что это за игра?
Думаете как провести новогоднюю ночь? Не знаете, чем заняться на каникулах? У нас, как обычно, есть идея – нужно купить настольную игру Дженга и провести время с весельем и пользой.
Вы еще не знаете, что такое Дженга? Или не знаете правил? Сейчас все расскажем.
ЧТО ЗА ИГРА – ДЖЕНГА
Jenga в переводе с суахили – «строить». Это полностью передает задачи игроков. Для начала нужно построить башню. Есть четкие правила, каким образом укладывать брусочки для башни дженга. Когда башня построена, собственно и начинается игра.
Игрокам нужно доставать по одному бруску из башни и перекладывать на самый верх. Трогать башню одновременно можно только одной рукой. Можно подталкивать брусочки, чтобы понять, получится ли их вытащить, никакого обязательства переложить именно потроганный брусок у игроков нет.
В русской интерпретации дженгу называют «падающая башня». Это именно то, чем кончается игра – башня может упасть. А вот по чьей вине – определит точность, ловкость, глазомер и терпение игроков.
ЧЕМ РАЗНЫЕ ДЖЕНГИ ОТЛИЧАЮТСЯ ДРУГ ОТ ДРУГА
Jenga CLASSIC
Дженга классик — артикул A2120 — берите классический вариант дженги, если вы еще не играли в эту игру. Классика подойдет людям и спокойным, и активным. В нее можно играть и компанией и в одиночку. В классической версии Jenga деревянные бруски. Строим башню, вытаскиваем кубики и кладем на самый верх. Это отличный подарок и детям и взрослым.
Jenga BOOM
Дженга Бум – артикул A2028 – это игра на скорость. Когда башня из брусков установлена, запускается таймер. Игра продолжается только пока «горит» шнур. Когда время закончится, рванет «бомба» и башня обрушится. На чьем ходу взорвалась башня, тот и проиграл. Азарт невероятный. В этой версии игры бруски тоже деревянные, как и в классической Дженге
Jenga Quake
Квейк – артикул A5405 – еще один азартный вариант игры в Дженгу. Башня устанавливается на подставку. В какой-то момент (не известно в какой) подставка начнет вибрировать, и башня рухнет. Чей был ход? Он будет считаться проигравшим. Если подставка еще не вибрирует, торопитесь! Брусочки в игре сделаны из пластика, по цвету он похож на раскаленные камни. Для игрушки потребуются батарейки – они устанавливаются в подставку.
Jenga GOLD
Дженга Голд – (артикул B7430) – одна из самых новых версий игры. Правила у нее классические, вот только башню нужно строить не из деревянных брусков, а из золотых слитков. Конечно, золото это не настоящее, а пластиковое. Но зато игра выглядит необычно и очень богато.
В ЧЕМ ПОЛЬЗА НАСТОЛЬНОЙ ИГРЫ ДЖЕНГА
Покупатели часто спрашивают нас, есть ли польза от той или иной игрушки, или это просто развлечение. Так вот, что касается игры Дженга – польза несомненная.
Игра развивает глазомер, точность, усидчивость, терпение, ловкость и моторику. Показывает, что такое равновесие и баланс. Что немаловажно, ребенок может играть один – эта игра увлекает даже без соперников. А уж если собирается целая компания, то время за игрой летит незаметно.
Купить дженгу можно в любом ее исполнении – все вариации игры интересные. Лучше дарить такую игру детям-школьникам или взрослым. Возрастное ограничение от производителя –от 6 лет и старше. Делайте заказ через сайт или по телефону – доставка по Санкт-Петербургу, Москве и всей России.
А если вы еще не определились с выбором, заходите в раздел Настольные игры и посмотрите на другие игры, которые сейчас есть в наличии. Мы можем помочь вам, достаточно просто позвонить или написать в онлайн-консультанте. Ждем вас!
Дженга или падающая башня — история и правила игры
Слово «jenga» — это повелительное наклонение от «kujenga», в переводе с суахили означающее «строить». Что же строят в этой игре? Башню! До тех пор, пока она не упадёт…Казалось бы, какая может быть игра с деревянными брусочками? Ну, построить что-то, используя как конструктор, вот, пожалуй, и всё. Однако разработчица игры — Лесли Скотт— подошла к вопросу постройки совсем с другой стороны. Строить в «Дженге» придётся с умом. Сама идея игры зародилась в семье Лесли в начале 1970-х, и изначально в ней использовались обыкновенные детские деревянные кубики. Затем были сделаны специальные игровые блоки: длина каждого блока в три раза больше его ширины, а высота примерно равна половине его ширины.
Чтобы раскрыть интригу башни, нужно ознакомиться с самими правилами игры. Итак, в игре участвуют 54 деревянных блока. Для начала игры надо построить башню высотой в 18 этажей. Каждый этаж состоит из трёх блоков, положенных вплотную и параллельно друг другу. Блоки каждого следующего этажа кладутся перпендикулярно блокам предыдущего этажа.
После того как башня построена, игра начинается. У игроков появляется право хода. Первым ходит тот, кто строил башню. Ход в «Дженге» состоит из вытаскивания одного блока из любого уровня (за исключением того, который прямо под недостроенным верхним) башни. Вытащенный блок нужно разместить наверху башни так, чтобы её было возможно завершить (нельзя достраивать этажи под незавершённым верхним уровнем). Для извлечения блока разрешено использовать только одну руку; вторая рука тоже может использоваться, но дотрагиваться до башни одновременно можно только одной рукой. Блоки можно подталкивать, чтобы найти тот, который свободнее всего сидит. Любой подвинутый блок можно оставить на месте и не продолжать его доставать, если это приведёт к падению башни. В игре хватает динамики: ход заканчивается тогда, когда следующий игрок дотронется до башни, или когда пройдёт 10 секунд, в зависимости от того, какое событие случится раньше.
С использованием башни из этой игры в школах США проводятся опыты на уроках физики.
Конец игры ознаменовывает падение башни, то есть падение любого блока кроме того, который игрок в данный ход пытается расположить наверху башни. Проигравшим считается тот, чей ход произвёл обвал башни. Однако если упало всего несколько блоков, то игроки могут по желанию продолжить игру. Будьте уверены, в первые разы ваша башня будет падать очень быстро.
Правила кажутся простыми, но игра недаром за более чем 30 лет своего существования распространилась по всему миру и завоевала тысячи поклонников. Потому что «Дженга» – игра на ловкость рук, смекалку и чувство равновесия. Строить башню могут и дети. Им особенно полезна эта игра, так как задействована моторика, развивается умение устанавливать причинно-следственные связи, прививается усидчивость и аккуратность. Играть можно также разбившись на команды, что поможет объединить малознакомую компанию.
Опытные игроки разработали не одну систему: какие бруски, в какой последовательности вытаскивать, чтобы выиграть. Но общая закономерность одна: лучше вытаскивать брусочки по всей высоте башни, не концентрируясь на одной из частей.
Несмотря на британское гражданство, Лесли Скотт родилась в Восточной Африке, говорит как на английском, так и на суахили. Поэтому она и дала своей игре такое броское, непривычное для уха название.
Кроме классической версии игроки придумали ещё множество дополнительных «фишек», чтобы разнообразить и усложнить игру. Те, кто достиг феерических высот в строительстве башни, пишут на боковых гранях номера, берут игральный кубик и перемещают только тот брусок, чей номер выпал на кубике. Другие, ради веселья изображают на гранях задания (типа игры в фанты), например «Расскажи анекдот», «Изобрази грустного кролика». Игрок, перемещая любой брусок, обязан выполнить задание, на нём начертанное.
Конечно же, производители, видя такое увлечение, не обошли игру различными «репликами» и вариациями. Так, появилась «Дженга» с разноцветными блоками, игра с увеличенным количеством блоков, игра, в которой блоки увеличены во много раз (башня достигает полутора метров!), и, конечно же, игры-приложения для всевозможных мобильных устройств: там блоки вытаскиваются одним движением пальца.
Статья подготовлена по материалам Википедии
Настольная игра Дженга Землетрясение (Джанга, Башня, Jenga Quake)
Что такое «не везёт»
Японию вновь накрыла волна землетрясений. Подземные толчки и колебания в который раз разбудили жителей и «попросили» покинуть их свои дома. Из-за своего географического расположения (страна находится на стыке четырех плит), Япония больше других государств подвержена подобным стихийным бедствиям.
«Как хорошо, что мы живем не в Японии», — наверняка подумали вы. Однако, для тех, кого завораживают подобные стихийные бедствия и тех, кто зачем-то хотел бы пережить подобный адреналин, есть отличная настольная игра Дженга Землетрясение. Физически вы никак не пострадаете, испытав игровое землетрясение, а вот морально – да, в случае вашего проигрыша.
Устроим встряску!
Дизайн настольной игры Дженга Землетрясение напоминает гору каких-то обломков, собранных в одну кучу. Такое впечатление, что где-то недалеко действительно произошло землетрясение, из разрушенных завалов кто-то выбрал обломанные брусочки и вручил их нам, мол, берите, играйте.
Ну, это всё, конечно, шутки. Брусочков в коробке, как обычно тридцать шесть, только в этот раз они не деревянные, а пластиковые и окрашены в серый и оранжевый цвет. Если взглянуть издалека – похоже на лаву, которая проступила в результате сильного землетрясения и извержения вулкана. Компоненты приятные на ощупь и изготовлены из качественной пластмассы. Лично мы считаем, что дизайн вполне оправдан темой выпуска а потому ставим твёрдую пятерку.
Кроме брусков, в коробке еще находится основа, чем-то напоминающая маленькое жерло вулкана. Именно на неё, как на платформу, нужно класть бруски по три на этаж, выстраивая каждый следующий перпендикулярно предыдущему.
Перед началом игры Дженга Землетрясение нужно нажать на рычаг с боку основы, чтоб привести механизм в действие. Как и во всех играх серии Дженга, вашей задачей будет по очереди вытаскивать брусок из башни и класть его на верхний этаж так, чтоб конструкция осталась стоять на месте еще 5 секунд после вашего хода. Выполнять это задание можно только одной рукой, не помогая второй. Строить следующий этаж, когда предыдущий еще не закончен (должно быть три бруска) нельзя. Игра закончится, когда по чьей-нибудь неосторожности или под действием механизма основы, башня рухнет. Победителем будет считаться игрок, который последним походил успешно.
Держитесь крепче
Настольная игра Дженга Землетрясение не сможет вызвать настоящее колебание земной поверхности, однако, лично вас тряхнет неслабо. Вся партия проходит с легким волнением, ведь точно не знаешь, когда именно пошатнется земля под ногами. Как и в реальной жизни, землетрясение нельзя предугадать. Даже учёные пока не нашли достоверный способ предсказывания этих колебаний. Считается, что животные хорошо чувствуют приближение землетрясений. Только, как это может помочь?
Рекомендуем купить игру Дженга Землетрясение тем, кто уже вдоволь наигрался в оригинальные версии Дженга (Джанга, Jenga) и Джанга (Jenga, Дженга, Башня), и хочет добавить каких-нибудь усложнений в любимую игру.
Дженга как питьевая игра: правила и идеи
Какая вы команда НФЛ?
Викторина:📖 Содержание:
Оборудование для Дженга как питьевой игры ✅
- Дженга
- Ручка (если хотите, используйте несколько цветов)
- Алкоголь
Как играть в Дженга как на выпивку 🤓
Как и в исходной версии Дженга, камни помещаются в башню. Отличие от исходной версии Дженга в том, что на каждом камне есть разные метки. Этикетки на камнях — инструкции для игрока, вытащившего камень из башн.
Правила Дженга как питьевой игры 🤨
Цель, как и в оригинальной версии, — положить последний камень на вершину башни, прежде чем башня рухнет. Все, кроме победителя, должны пить.
Правила Дженга как питьевой игры такие же, как и в обычной игре Дженга. Однако на отдельных камнях написаны разные слова. Эти слова являются инструкциями для игрока, который вытащил камень. Можно пометить любое количество камней.
При написании камней требуется творчество. Но если вы не хотите заниматься творчеством, вот несколько советов для вас.
Дженга идеи ярлыков 💡
Вот несколько замечательных советов, как можно маркировать деревянные кирпичи.:
Напиток 1
Выпить один раз
Напиток 2
Пить дважды
Напиток 3
Пьет трижды
Распределить 1
Найдите того, кому нужно выпить хоть раз
Разделить 2
Ищу кого-нибудь выпить дважды
Разделить 3
Ищу того, кому нужно выпить три раза
Групповое давление
Выпейте один раз за каждого подыгрывающего игроку.
Я Никогда Не
Все мы это знаем и любим. Чтобы найти отличные идеи Я Никогда Не, взгляните на наши Список вопросов Я Никогда Не.
Левша
Выберите игрока, которому разрешено пить только левой рукой. Если игрок выпивает по праву, он должен выпить пенальт.
Правило настройки
Создайте правило. Например, каждый должен присесть на корточки перед тем, как пить, или выпить тост перед тем, как пить.
Правда или действие
Правда или действие — одна из лучших игр для вечеринок, которая также идеально подходит для Дженга. Вы также можете нарисовать ангела на одном кубике для «истины» и дьявола на другом для испытания. Чтобы найти отличные идеи Правда или действие, загляните в наш огромный список: Лучшие вопросы о Правда или действие
Вам также может понравиться: Правда или действие Дженга
Карлик
Самый маленький игрок должен выпить трижды, а затем выбрать того, кто также должен выпить трижды.
Гигантский
Самый крупный игрок должен выпить трижды, а затем выбрать того, кто тоже должен выпить трижды.
Сидя на коленях
Игроку разрешается выбрать игрока, который будет сидеть на коленях у другого игрока, пока игра не закончится.
Текила
Выпейте рюмку текилы
Биполярный
Оскорбите человека слева от вас и сделайте комплимент человеку справа от ва.
Выбрасывать
Вы можете разговаривать только с объектами, но не с другими людьми до конца игр.
Палец
Вы можете определить место, где держите большой палец. Каждый раз, когда вы удерживаете большой палец на месте, другие игроки также должны держать свои пальцы в этом положении. Самый медленный игрок должен пить.
Группы 80-х
Назови три группы из восьмидесятых или выпей три раза.
Группы 70-х
Назови три группы из семидесятых или выпей три раза.
Титаник
Корабль идет ко дну, все должны выпить свой напиток.
Изменение имени
Вы можете присвоить новое имя другому игроку. К концу игры это должно быть решено с его новым именем. Если используется старое название, надо пить.
Шутка
Расскажи анекдот или выпей три раза.
Часы тикают
С этого момента у каждого игрока осталось всего 10 секунд, чтобы завершить свой хо.
Дедушка
Вы должны вести себя как дедушка до конца игры.
Смена платья
Выберите двух игроков, они должны поменяться выбранным предметом одежды друг с друго.
Отжимание
Мужчинам нужно сделать 30 отжиманий или трижды выпить. Женщинам нужно сделать 5 отжиманий или дважды выпить.
Разворот
С этого момента игра продолжается в обратном направлении.
Надеемся, вам понравятся правила Дженга как питьевой игры! Пить ответственно!
✍️ 7 сентябрь 2020 г.
dfunckt / django-rules: отличная авторизация Django, без базы данных
правил
— это крошечное, но мощное приложение, предоставляющее разрешения на уровне объекта для
Django, не требуя базы данных. По сути, это общий фреймворк.
для построения систем на основе правил, подобных деревьям решений. Это также может быть
используется как отдельная библиотека в других контекстах и фреймворках.
Характеристики
правил
вас охватит. правил
это:
- Документировано , протестировано , надежно и проста в использовании .
- Универсальный . Украшайте вызываемые объекты для построения сложных графов предикатов. Предикаты могут быть любого типа вызываемыми — простые функции, лямбды, методы, вызываемые объекты класса, частичные функции, декорированные функции, ничего действительно.
- Хороший гражданин Джанго . Полная интеграция с представлениями Django, шаблоны и администратор для тестирования разрешений на уровне объекта.
- Эффективный и умный . Не нужно возиться с базой данных, чтобы понять выяснить, действительно ли Джон написал эту книгу.
- Простой . Погрузитесь в код. Вам понадобится 10 минут, чтобы понять, как это работает.
- Мощный .
rules
поставляется с расширенными функциями, такими как контекст вызова и хранилище для произвольных данных, пропуская оценку предикаты при определенных условиях, регистрация оцененных предикатов и многое другое!
Содержание
Требования
rules
требует Python 3.6 или новее. Последняя версия с поддержкой Python 2.7 правила
2.2. При желании его можно интегрировать с Django, и в этом случае
требуется Django 2.2 или новее.
Примечание : В любой момент времени правила
будут поддерживать все
в настоящее время поддерживаются версии Django, но поддержка этих версий прекращается.
которые достигли конца срока службы в второстепенных выпусках. См. Поддерживаемые версии
раздел на веб-сайте Django Project, чтобы узнать о текущем состоянии и сроках.
Обновление с 2.x
Существенных изменений между правилами нет.
2.x и 3.x кроме удаления
поддержка Python 2, поэтому перед обновлением до 3.x вам просто нужно убедиться
вы используете поддерживаемую версию Python 3.
Обновление 1.x
- Поддержка Python 2.6 и 3.3, а также версий Django до 1.11 была упавший.
- Исключение
SkipPredicate
и методskip ()
изPredicate
, которые использовались для обозначения того, что предикат должен быть пропущен, были удаленный. Для этого вы можете вернутьNone
из своего предиката. - API-интерфейсы для замены предиката правила были переименованы, и их
поведение изменилось.
replace_rule
иreplace_perm
функции иreplace_rule
методRuleSet
был переименован вset_rule
,set_perm
иRuleSet.set_perm
соответственно. Старое поведение было вызватьKeyError
, если правила с указанным именем не существует. С версия 2.0 это было изменено, и вы можете безопасно использоватьset_ *
для установки предикат правила без необходимости сначала убедиться, что правило существует.
Как установить
Использование pip:
Вручную:
$ git clone https://github.com/dfunckt/django-rules.git $ cd django-rules $ python setup.py установить
Выполнить тесты с:
Вы также можете прочитать Лучшие практики для получения общих советов о том, как
используйте правила
.
Настройка Django
Добавить правил
в INSTALLED_APPS
:
INSTALLED_APPS = ( # ... 'правила', )
Добавить серверную часть аутентификации:
AUTHENTICATION_BACKENDS = ( 'правила.permissions.ObjectPermissionBackend ', 'django.contrib.auth.backends.ModelBackend', )
Использование правил
rules
основан на идее, что вы поддерживаете dict-подобный объект, который отображает
строковые ключи, используемые в качестве идентификаторов какого-либо вида, для вызываемых, вызываемых предикат . Этот dict-подобный объект на самом деле является экземпляром RuleSet
и
предикаты являются экземплярами Predicate
.
Создание предикатов
Давайте на мгновение проигнорируем наборы правил и определим предикат.В
Самый простой способ — использовать декоратор @predicate
:
>>> @ rules.predicate >>> def is_book_author (пользователь, книга): ... вернуть book.author == пользователь ... >>> is_book_author <Предикат: объект is_book_author в 0x10eeaa490>
Этот предикат вернет True
, если автор книги — указанный пользователь, Неверно
иначе.
Предикаты могут быть созданы из любого вызываемого объекта, который принимает все от нуля до два позиционных аргумента:
-
fn (объект, цель)
-
fn (obj)
-
fn ()
Это их общая форма.Если смотреть с точки зрения авторизации в Django, эквивалентные подписи:
-
fn (пользователь, объект)
-
fn (пользователь)
-
fn ()
Предикаты могут делать практически все с заданными аргументами, но должны
всегда возвращать Истина
, если условие, которое они проверяют, истинно, Ложь
иначе. rules
поставляется с несколькими предопределенными предикатами, которые вы можете
читайте позже в Справочнике по API, которые в основном полезны при работе с
с авторизацией в Django.
Настройка правил
Давайте представим, что мы хотим разрешить авторам редактировать или удалять свои книги, но не книги других авторов. Итак, по сути, от чего зависит, будет ли автор может редактировать или может удалить данная книга — независимо от того, являются ли они ее автор .
В правилах
такие требования смоделированы как правила и . Правило — это карта
уникальный идентификатор (например, «можно редактировать») предиката. Правила сгруппированы
вместе в набор правил . правил
имеет два предопределенных набора правил:
- Набор правил по умолчанию, в котором хранятся общие правила.
- Другой набор правил, хранящих правила, которые служат разрешениями в Django. контекст.
Итак, давайте определим нашу первую пару правил, добавив их к общему правилу.
задавать. Мы можем использовать предикат is_book_author
, который мы определили ранее:
>>> rules.add_rule ('can_edit_book', is_book_author) >>> rules.add_rule ('can_delete_book', is_book_author)
Предполагая, что у нас есть данные, теперь мы можем проверить наши правила:
>>> из django.contrib.auth.models импорт пользователя >>> из books.models import Book >>> guidetodjango = Book.objects.get (isbn = '978-1-4302-1936-1') >>> guidetodjango.author <Пользователь: adrian> >>> Адриан = User.objects.get (имя пользователя = 'Адриан') >>> rules.test_rule ('can_edit_book', Адриан, Guidetodjango) Истинный >>> rules.test_rule ('can_delete_book', Адриан, Guidetodjango) Правда
Красиво … но не круто.
Объединение предикатов
Предикаты сами по себе не так полезны — не более полезны, чем любые другие функция будет.Однако предикаты можно комбинировать с помощью бинарных операторов. создавать более сложные. Предикаты поддерживают следующие операторы:
-
P1 & P2
: возвращает новый предикат, который возвращаетTrue
, если оба предикаты возвращаютTrue
, в противном случаеFalse
. Если P1 возвращаетЛожь
, P2 не будет оцениваться. -
P1 | P2
: возвращает новый предикат, который возвращаетИстина
, если любой из predicates возвращаетTrue
, в противном случаеFalse
.P2 : возвращает новый предикат, который возвращаетИстина
, если один из предикаты возвращаетTrue
, а другой возвращаетFalse
, иначеНеверно
. -
~ P
: возвращает новый предикат, который возвращает отрицательный результат исходный предикат.
Предположим, что для них требовалось разрешить пользователю редактировать данную книгу. быть либо автором книги, либо членом группы «редакторы». Разрешение пользователи, желающие удалить книгу, по-прежнему должны определяться тем, является ли пользователь автор книги.
С правилами
легко реализовать. Нам нужно было бы определить другое
предикат, который вернет True
, если данный пользователь является членом
группа «редакторы», Неверно
иначе. Встроенная фабрика is_group_member
пригодится:
>>> is_editor = rules.is_group_member ('редакторы') >>> is_editor <Предикат: is_group_member: объект редакторов в 0x10eee1350>
Мы могли бы объединить его с предикатом is_book_author
, чтобы создать новый
который проверяет любое условие:
>>> is_book_author_or_editor = is_book_author | is_editor >>> is_book_author_or_editor <Предикат: (is_book_author | is_group_member: editors) объект в 0x10eee1390>
Теперь мы можем обновить наше правило can_edit_book
:
>>> правила.set_rule ('can_edit_book', is_book_author_or_editor) >>> rules.test_rule ('can_edit_book', Адриан, Guidetodjango) Истинный >>> rules.test_rule ('can_delete_book', Адриан, Guidetodjango) Правда
Посмотрим, что будет с другим пользователем:
>>> martin = User.objects.get (имя пользователя = 'martin') >>> список (martin.groups.values_list ('name', flat = True)) ['редакторы'] >>> rules.test_rule ('can_edit_book', martin, guidetodjango) Истинный >>> rules.test_rule ('can_delete_book', martin, guidetodjango) Ложь
Отлично.
До сих пор мы использовали только базовую общую структуру для определения и
правила тестирования. Этот уровень совершенно не специфичен для Django; это может быть использовано в
любой контекст. На самом деле нет импорта чего-либо, связанного с Django, в
все приложение (кроме модуля rules.templatetags
). правила
однако можно
тесно интегрироваться с Django для авторизации.
Использование правил в Django
правил
может предоставлять разрешения на уровне объектов в Django.Это приходит
с бэкэндом авторизации и парой тегов шаблонов для использования в вашем
шаблоны.
Разрешения
В правилах
разрешения представляют собой особый тип правил. Вы все еще определяете
rules путем создания и комбинирования предикатов. Однако эти правила необходимо добавить
к набору правил для конкретных разрешений, который включает правил
, чтобы они могли
быть подхваченным по правилам бэкэнд авторизации
.
Создание разрешений
Соглашение об именах разрешений в Django — app_label.action_object
,
и нам нравится придерживаться этого. Добавим правила для книг. Change_book
и books.delete_book
разрешений:
>>> rules.add_perm ('books.change_book', is_book_author | is_editor) >>> rules.add_perm ('books.delete_book', is_book_author)
Видите разницу в API? add_perm
добавляет к конкретным разрешениям
набор правил, тогда как add_rule
добавляет к общему набору правил по умолчанию. Это
однако важно знать, что эти два набора правил являются отдельными, а это означает, что
добавление правила в одно не делает его доступным для другого.
Проверка разрешения
Давайте продолжим и проверим, есть ли у adrian
разрешение на изменение гидtodjango
книга:
>>> adrian.has_perm ('books.change_book', guidetodjango) Ложь
Когда вы вызываете метод User.has_perm
, Django запрашивает каждый бэкэнд в settings.AUTHENTICATION_BACKENDS
, имеет ли пользователь данное разрешение
для объекта. При запросе разрешений на объект Django по умолчанию
бэкэнд аутентификации всегда возвращает False
. правил
поставляется с
бэкэнд авторизации, который может предоставлять разрешения на уровне объекта с помощью
изучение набора правил для конкретных разрешений.
Добавим правил
бэкэнд авторизации в настройки:
AUTHENTICATION_BACKENDS = ( 'rules.permissions.ObjectPermissionBackend', 'django.contrib.auth.backends.ModelBackend', )
Теперь повторная проверка дает adrian
необходимые разрешения:
>>> адриан.has_perm ('books.change_book', guidetodjango) Истинный >>> adrian.has_perm ('books.delete_book', guidetodjango) Истинный >>> martin.has_perm ('books.change_book', guidetodjango) Истинный >>> martin.has_perm ('books.delete_book', guidetodjango) Ложь
Разрешения в моделях
ПРИМЕЧАНИЕ. Функции, описанные в этом разделе, работают только с Python 3+.
Обычно есть набор разрешений для модели, как то, что предлагает Django с
разрешения модели по умолчанию (например, добавить , изменить и т. д.). При использовании правил
в качестве серверной части проверки разрешений вы можете объявить разрешения на уровне объекта для
любую модель аналогичным образом, используя новую опцию Meta
.
Во-первых, вам нужно переключить базу и метакласс вашей модели на слегка расширенный
версии представлены в правилах . contrib.models
. Есть несколько классов и миксинов
вы можете использовать, в зависимости от того, используете ли вы уже настраиваемую базу и / или метакласс
для ваших моделей или нет. Удлинители очень тонкие и не влияют на модели.
поведение любым способом, кроме как заставить его регистрировать разрешения.
Если вы используете стандартную модель
django.db.models.Model
в качестве основы для своих моделей, просто переключитесь наRulesModel
, и все готово.Если у вас уже есть настраиваемый базовый класс, добавляющий общие функции к вашим моделям, добавить
RulesModelMixin
к классам, от которых он наследуется, и установитьRulesModelBase
как его метакласс, например:из модели импорта django.db.models из rules.contrib.models импортировать RulesModelBase, RulesModelMixin класс MyModel (RulesModelMixin, Модель, метакласс = RulesModelBase): ...
Если вы используете собственный метакласс для своих моделей, вы уже знаете, как сделайте его наследовать от
RulesModelBaseMixin
самостоятельно.
Затем создайте свои модели таким образом, предполагая, что вы используете RulesModel
в качестве базовой
напрямую:
правил импорта из rules.contrib.models импортировать RulesModel Книга классов (RulesModel): класс Мета: rules_permissions = { "добавить": rules.is_staff, «читать»: правила.is_authenticated, }
Это будет эквивалентно следующим звонкам:
rules.add_perm ("app_label.add_book", rules.is_staff) rules.add_perm ("app_label.read_book", rules.is_authenticated)
В RulesModelMixin
есть методы, которые можно перезаписать, чтобы настроить
как регистрируются разрешения модели. Подробности см. В задокументированном исходном коде.
если вам это нужно.
Особый интерес представляет метод класса get_perm
из RulesModelMixin
, который может
использоваться для преобразования типа разрешения в соответствующее полное имя разрешения.Если
вам нужно программно запросить какой-либо тип разрешения для данной модели,
это удобно:
, если user.has_perm (Book.get_perm ("читать")): ...
Разрешения в представлениях
rules
поставляется с набором декораторов представлений, которые помогут вам
авторизация в ваших представлениях.
Использование декоратора представлений на основе функций
Для представлений на основе функций вы можете использовать декоратор permission_required
:
из django.shortcuts import get_object_or_404 из правил.contrib.views import permission_required from posts.models import Post def get_post_by_pk (запрос, post_id): return get_object_or_404 (Сообщение, pk = post_id) @permission_required ('posts.change_post', fn = get_post_by_pk) def post_update (запрос, post_id): # ...
Использование простое, но в приведенном выше примере есть
выделяется, и это функция get_post_by_pk
. Эта функция, учитывая
текущий запрос и все аргументы, переданные в представление, отвечает за
получение и возврат объекта для проверки разрешений — i.е. в Отправьте экземпляр
с PK, равным post_id
в примере.
Этот конкретный вариант использования довольно распространен, поэтому, чтобы не печатать, правила
поставляется с универсальной вспомогательной функцией, которую вы можете использовать декларативно.
Пример ниже эквивалентен приведенному выше:
из rules.contrib.views import permission_required, objectgetter from posts.models import Post @permission_required ('posts.change_post', fn = objectgetter (Post, 'post_id')) def post_update (запрос, post_id): #...
Для получения дополнительной информации о декораторе и вспомогательной функции см. rules.contrib.views модуль
.
Использование миксина представлений на основе классов
Django включает набор миксинов доступа, которые вы можете использовать в своих классах.
просмотров для обеспечения авторизации. правил
расширяет эту структуру, чтобы обеспечить
разрешения на уровне объекта через миксин PermissionRequiredMixin
.
В следующем примере автоматически проверяется разрешение на
экземпляр, возвращенный методом представления get_object
:
из django.views.generic.edit импорт UpdateView из rules.contrib.views import PermissionRequiredMixin from posts.models import Post класс PostUpdate (PermissionRequiredMixin, UpdateView): model = Опубликовать Разрешение_required = 'posts.change_post'
Вы можете настроить объект, переопределив get_object
или get_permission_object
.
Для получения дополнительной информации см. Документацию Django и rules.contrib.views модуль
.
Автоматическая проверка разрешений в зависимости от типа представления
Если вы используете механизмы, предусмотренные правилами .contrib.models
для регистрации разрешений
для ваших моделей, как описано в разделе «Разрешения в моделях», есть еще один удобный
mixin для доступных вам представлений на основе классов.
rules.contrib.views.AutoPermissionRequiredMixin
может распознавать тип представления
он используется и автоматически проверяет наличие соответствующего разрешения.
Этот пример представления без какой-либо дополнительной настройки автоматически проверяет наличие
разрешение "posts.change_post"
, учитывая, что ярлык приложения — "posts"
:
из django.views.generic импорт UpdateView из rules.contrib.views импортировать AutoPermissionRequiredMixin from posts.models import Post класс UpdatePostView (AutoPermissionRequiredMixin, UpdateView): model = Опубликовать
По умолчанию общие представления CRUD из django.views.generic
отображаются на
родные типы разрешений Django ( добавить , изменить , удалить и просмотреть ). Однако,
предопределенные сопоставления могут быть расширены, изменены или полностью заменены, когда
подкласс AutoPermissionRequiredMixin
.См. Полностью документированный исходный код
для получения подробной информации о том, как это сделать правильно.
Разрешения и правила в шаблонах
rules
поставляется с двумя шаблонными тегами, позволяющими проверять правила и
разрешения в шаблонах.
Добавьте правил
к своим INSTALLED_APPS
:
INSTALLED_APPS = ( # ... 'правила', )
Затем в вашем шаблоне:
{% load rules%} {% has_perm 'books.change_book' авторская книга как can_edit_book%} {% if can_edit_book%} ... {% endif%} Пользователь {% test_rule 'has_super_feature' как has_super_feature%} {% if has_super_feature%} ... {% endif%}
Разрешения в админке
Если вы настроили правил
для использования с разрешениями в Django, вы почти
установить также использовать правила
для авторизации любых действий добавления / изменения / удаления в
Админ. Администратор запрашивает четыре разных разрешения, в зависимости от действия:
-
.add_ -
.view_ <имя модели> -
.change_ -
<метка_приложения> .delete_ <имя модели>
-
Примечание. Разрешение на просмотр является новым в Django v2.1 и не должно добавляться в более ранних версиях.
Первые четыре очевидны. Пятое — это необходимое разрешение для приложения.
для отображения в «панели управления» администратора. Его переопределение не ограничивает доступ к добавлению,
изменить или удалить просмотры.Вот несколько правил для нашего воображаемого приложения books
в качестве примера:
>>> rules.add_perm ('книги', rules.always_allow) >>> rules.add_perm ('books.add_book', is_staff) >>> rules.add_perm ('books.view_book', is_staff | has_secret_access_code) >>> rules.add_perm ('books.change_book', is_staff) >>> rules.add_perm ('books.delete_book', is_staff)
Django Admin не поддерживает права доступа к объектам в том смысле, что он будет никогда не спрашивайте разрешения на выполнение действия над объектом , только если пользователю разрешено действовать на ( любых ) экземплярах модели.
Если вы хотите сообщить Django, есть ли у пользователя разрешения на определенные
объект, вам придется переопределить следующие методы модели ModelAdmin
:
-
has_view_permission (пользователь, obj = None)
-
has_change_permission (пользователь, obj = None)
-
has_delete_permission (пользователь, obj = None)
rules
поставляется с настраиваемым подклассом ModelAdmin
, rules.contrib.admin.ObjectPermissionsModelAdmin
, который отменяет эти
методы для передачи отредактированного экземпляра модели бэкэндам авторизации,
таким образом, разрешая разрешения для каждого объекта в Admin:
# books / admin.py от администратора импорта django.contrib из rules.contrib.admin импортировать ObjectPermissionsModelAdmin из .models import Book класс BookAdmin (ObjectPermissionsModelAdmin): проходить admin.site.register (Книга, BookAdmin)
Теперь это позволяет вам указывать разрешения следующим образом:
>>> правила.add_perm ('книги', rules.always_allow) >>> rules.add_perm ('books.add_book', has_author_profile) >>> rules.add_perm ('books.change_book', is_book_author_or_editor) >>> rules.add_perm ('books.delete_book', is_book_author)
Чтобы сохранить обратную совместимость, Django запросит либо представление , либо изменить разрешение . Для максимальной гибкости правил
ведет себя незаметно
другое: правила
будет запрашивать разрешение на изменение тогда и только тогда, когда нет правила
существует для разрешения просмотра.
Разрешения в Django Rest Framework
Подобно rules.contrib.views.AutoPermissionRequiredMixin
, есть rules.contrib.rest_framework.AutoPermissionViewSetMixin
для наборов представлений в Django
Остальные рамки. Разница в том, что он не получает разрешения от типа
представления, но из действия API ( создать , получить и т. д.), которое пытались
выполнила. Конечно, это также требует, чтобы вы объявили свои модели, как описано в
Разрешения в моделях.
Вот возможный ModelViewSet
для модели Post
с полностью автоматизированным CRUD
проверка разрешений:
из rest_framework.serializers import ModelSerializer из rest_framework.viewsets импортировать ModelViewSet из rules.contrib.rest_framework импорт AutoPermissionViewSetMixin from posts.models import Post класс PostSerializer (ModelSerializer): класс Мета: model = Опубликовать fields = "__all__" класс PostViewSet (AutoPermissionViewSetMixin, ModelViewSet): queryset = Сообщение.objects.all () serializer_class = PostSerializer
По умолчанию действия CRUD ModelViewSet
сопоставляются с собственным
Типы разрешений Django ( добавить , изменить , удалить и просмотреть ). Список
Для действия не включена проверка разрешений. Однако предопределенные отображения
может быть расширен, изменен или полностью заменен при использовании (или создании подкласса) AutoPermissionViewSetMixin
. Пользовательские действия API, определенные через @action
декоратор также может быть отображен.См. Полностью документированный исходный код для
подробности о том, как правильно настроить поведение по умолчанию.
Расширенные функции
Пользовательские наборы правил
Вы можете создать столько наборов правил, сколько вам нужно:
>>> features = rules.RuleSet ()
И манипулируйте ими, добавляя, удаляя, запрашивая и проверяя правила:
>>> features.rule_exists ('has_super_feature') Ложь >>> is_special_user = rules.is_group_member ('специальный') >>> особенности.add_rule ('has_super_feature', is_special_user) >>> 'has_super_feature' в функциях Истинный >>> особенности ['has_super_feature'] <Предикат: is_group_member: специальный объект в 0x10eeaa500> >>> features.test_rule ('has_super_feature', Адриан) Истинный >>> features.remove_rule ('has_super_feature')
Обратите внимание, однако, что пользовательские наборы правил недоступны в шаблонах Django — вам нужно самостоятельно обеспечить интеграцию.
Контекст вызова
Новый контекст создается в результате вызова Predicate.test ()
и является
действует только на время вызова. Контекст — это простой dict
которые вы можете использовать для хранения произвольных данных (например, кеширование вычисленных значений,
установка флагов и т. д.), которые могут использоваться предикатами позже в цепочке.
Внутри функции предиката его можно использовать так:
>>> @predicate ... def mypred (a, b): ... значение = вычислить_дорогое_значение (а) ... mypred.context ['значение'] = значение ... вернуть True
Другие предикаты могут позже использовать сохраненные значения:
>>> @predicate ... def myotherpred (a, b): ... значение = myotherpred.context.get ('значение') ... если значение не равно None: ... вернуть do_something_with_value (значение) ... еще: ... вернуть do_something_without_value ()
Predicate.context
предоставляет один атрибут args
, который содержит
аргументы, переданные в test ()
в начале вызова.
Переплет «сам»
В теле функции предиката вы можете ссылаться на сам экземпляр предиката.
по названию, например. is_book_author
. Передача bind = True
в качестве ключевого слова
аргумент предиката Декоратор
позволит вам ссылаться на предикат
с сам
, что удобнее. Привязка к себе
просто синтаксическая
сахар. Фактически, следующие два эквивалента:
>>> @predicate ... def is_book_author (пользователь, книга): ... если is_book_author.context.args: ... вернуть пользователя == book.author ... вернуть False >>> @predicate (bind = True) ... def is_book_author (я, пользователь, книга): ... если self.context.args: ... вернуть пользователя == book.author ... вернуть False
Пропуск предикатов
Вы можете пропустить оценку, вернув None
из вашего предиката:
>>> @predicate (bind = True) ... def is_book_author (я, пользователь, книга): ... если len (self.context.args)> 1: ... вернуть пользователя == book.author ... еще: ... return Нет
Возвращение Нет
означает, что предикат не нужно оценивать, поэтому
оставив результат предиката до этого момента без изменений.
Оценка предиката журнала
правил
можно дополнительно настроить для регистрации отладочной информации в соответствии с правилами.
оценивается, чтобы помочь с отладкой ваших предикатов. Сообщения отправляются на
Уровень DEBUG для регистратора 'rules'
. Следующий dictConfig настраивает
регистратор консоли (поместите его в файл settings.py вашего проекта, если вы используете
правила с Django):
LOGGING = { 'версия': 1, disable_existing_loggers: Ложь, 'handlers': { 'приставка': { 'level': 'DEBUG', 'класс': 'ведение журнала.StreamHandler ', }, }, 'loggers': { 'правила': { 'обработчики': ['консоль'], 'level': 'DEBUG', 'распространять': Верно, }, }, }
Когда этот регистратор активен, каждый отдельный предикат будет иметь сообщение журнала. печатается при его оценке.
Лучшие практики
Прежде чем вы сможете проверить правила, эти правила должны быть зарегистрированы с набором правил, и для этого модули, содержащие определения ваших правил, должны быть импортный.
Для сложных проектов с несколькими предикатами и правилами может не быть Практично определить все ваши предикаты и правила в одном модуле. Это могло бы Лучше всего разделить их между любыми подкомпонентами вашего проекта. В Джанго В контексте эти подкомпоненты могут быть приложениями для вашего проекта.
С другой стороны, поскольку импорт предикатов из любого места в порядок определения правил может привести к циклическому импорту и разбитым сердцам, это лучше всего разделить предикаты и правила в разных модулях.
правил
можно дополнительно настроить для автоматического обнаружения модулей rules.py
в
ваши приложения и импортировать их при запуске. Чтобы правил
выполнялось, просто отредактируйте свой INSTALLED_APPS
настройка:
INSTALLED_APPS = ( # заменить 'rules' на: 'rules.apps.AutodiscoverRulesConfig', )
Примечание: На Python 2 вы также должны добавить следующее в верхнюю часть вашего rules.py
, иначе вы получите ошибки при импорте правил
сам:
из __future__ import absolute_import
Ссылка API
Основные API-интерфейсы доступны из корневого модуля rules
.Специфичный для Django
функциональность для администратора и представлений доступна из rules.contrib
.
Правила класса
. Предикат
Вы создаете экземпляров Predicate
, передавая вызываемый объект:
>>> def is_book_author (пользователь, книга): ... вернуть book.author == пользователь ... >>> pred = Предикат (is_book_author) >>> пред <Предикат: объект is_book_author в 0x10eeaa490>
При желании вы можете указать другое имя для используемого предиката. при осмотре:
>>> pred = Predicate (is_book_author, name = 'другое_имя') >>> пред <Предикат: объект another_name в 0x10eeaa490>
Кроме того, вы можете дополнительно указать bind = True
, чтобы иметь доступ к
экземпляр предиката с self
:
>>> def is_book_author (я, пользователь, книга): ... если self.context.args: ... вернуть пользователя == book.author ... вернуть False ... >>> pred = Predicate (is_book_author, bind = True) >>> пред <Предикат: объект is_book_author в 0x10eeaa490>
Методы экземпляра
-
тест (obj = None, target = None)
- Возвращает результат вызова переданного вызываемого объекта с нулем, одним или двумя позиционные аргументы, в зависимости от того, сколько он принимает.
Класс
правил.Набор правил
RuleSet
расширяет встроенный в Python тип dict. Следовательно, вы можете создать
и используйте набор правил так же, как и dict.
Методы экземпляра
-
add_rule (имя, предикат)
- Добавляет предикат к набору правил, присваивая его заданному имени правила.
Вызывает
KeyError
, если другое правило с таким именем уже существует. -
set_rule (имя, предикат)
- Установите правило с заданным именем, независимо от того, существует ли оно уже.
-
remove_rule (имя)
- Удалите правило с заданным именем. Вызывает
KeyError
, если правило с это имя не существует. -
rule_exists (имя)
- Возвращает
Истина
, если правило с данным именем существует,Ложь
в противном случае. -
test_rule (name, obj = None, target = None)
- Возвращает результат вызова
predicate.test (obj, target)
, гдепредикат
— это предикат правила с данным именем.ВозвратНеверно
, если правило с данным именем не существует.
Декораторы
-
@predicate
Декоратор, который создает предикат из любого вызываемого объекта:
>>> @predicate ... def is_book_author (пользователь, книга): ... вернуть book.author == пользователь ... >>> is_book_author <Предикат: объект is_book_author в 0x10eeaa490>
Настройка имени предиката:
>>> @predicate (имя = 'другое_имя') ... def is_book_author (пользователь, книга): ... вернуть book.author == пользователь ... >>> is_book_author <Предикат: объект another_name в 0x10eeaa490>
Переплет
сам
:>>> @predicate (bind = True) ... def is_book_author (я, пользователь, книга): ... если 'user_has_special_flag' в self.context: ... вернуть self.context ['user_has_special_flag'] ... вернуть book.author == пользователь
Предопределенные предикаты
-
always_allow ()
,always_true ()
- Всегда возвращает
Истинно
. -
always_deny ()
,always_false ()
- Всегда возвращает
Ложь
. -
is_authenticated (пользователь)
- Возвращает результат вызова
user.is_authenticated ()
. ВозвратНеверно
, если у данного пользователя нет методаis_authenticated
. -
is_superuser (пользователь)
- Возвращает результат вызова
user.is_superuser
. ВозвращаетЛожь
если у данного пользователя нет свойстваis_superuser
. -
is_staff (пользователь)
- Возвращает результат вызова
user.is_staff
. ВозвращаетЛожь
, если у данного пользователя нет свойстваis_staff
. -
is_active (пользователь)
- Возвращает результат вызова
user.is_active
. ВозвращаетЛожь
, если у данного пользователя нет свойстваis_active
. -
is_group_member (* группы)
- Фабрика, которая создает новый предикат, который возвращает
True
, если заданный Пользователь является членом всех данной группы,Ложь
в противном случае.
Ярлыки
Управление общим набором правил
-
add_rule (имя, предикат)
- Добавляет правило к общему набору правил. См.
RuleSet.add_rule
. -
set_rule (имя, предикат)
- Установите правило с заданным именем из общего набора правил. Видеть
RuleSet.set_rule
. -
remove_rule (имя)
- Удалить правило из общего набора правил. См.
RuleSet.remove_rule
. -
rule_exists (имя)
- Возвращает, существует ли правило в общем наборе правил. Видеть
RuleSet.rule_exists
. -
test_rule (name, obj = None, target = None)
- Проверяет правило с заданным именем. См.
RuleSet.test_rule
.
Управление набором правил разрешений
-
add_perm (имя, предикат)
- Добавляет правило в набор правил разрешений. См.
RuleSet.add_rule
. -
set_perm (имя, предикат)
- Заменить правило из набора правил разрешений. См.
RuleSet.set_rule
. -
remove_perm (имя)
- Удалить правило из набора правил разрешений. См.
RuleSet.remove_rule
. -
perm_exists (название)
- Возвращает, существует ли правило в наборе правил разрешений. Видеть
RuleSet.rule_exists
. -
has_perm (name, user = None, obj = None)
- Проверяет правило с заданным именем.См.
RuleSet.test_rule
.
Лицензия
django-rules
распространяется по лицензии MIT.
Авторские права (c) 2014 Акис Кесоглу
Разрешение предоставляется бесплатно любому лицу. получение копии этого программного обеспечения и сопутствующей документации файлы («Программное обеспечение») для работы с Программным обеспечением без ограничение, включая, помимо прочего, права на использование, копировать, изменять, объединять, публиковать, распространять, сублицензировать и / или продавать копий Программного обеспечения и разрешить лицам, которым Для этого предоставляется программное обеспечение при соблюдении следующих условий условия:
Приведенное выше уведомление об авторских правах и это уведомление о разрешении должны быть включены во все копии или существенные части Программного обеспечения.
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧЕННАЯ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕПРАВОМОЧНОСТЬ. НИ В КОЕМ СЛУЧАЕ АВТОРЫ ИЛИ АВТОРСКИЕ ПРАВА ДЕРЖАТЕЛИ НЕСУТ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УБЫТКИ ИЛИ ДРУГУЮ ОТВЕТСТВЕННОСТЬ, ВОЗНИКЛИ ЛИ В ДЕЙСТВИИ ДОГОВОРА, ИЛИ ИНОСТРАННЫМ ОТ, НЕ ИЛИ В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИЕ ДЕЯТЕЛЬНОСТИ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ.
maraujop / django-rules: Гибкий и масштабируемый бэкэнд авторизации Django для унифицированного управления разрешениями для каждого объекта
django-rules — это серверная часть авторизации Django, которая предлагает унифицированное управление авторизацией для каждого объекта.Он сильно отличается от других механизмов авторизации тем, что позволяет гибко управлять разрешениями для каждого объекта.
В правилах django каждое правило добавляет ограничение авторизации к данной модели. Ограничение авторизации проверяет, соответствует ли данный пользователь ограничению (например, если у пользователя есть права на выполнение определенного действия над объектом и т. Д.). Ограничение авторизации может быть логическим атрибутом, свойством или методом модели, в зависимости от того, что вы предпочитаете для каждого правила 🙂
Философия
django-rules стремится создать гибкий и масштабируемый бэкэнд авторизации.Почему это лучше, чем другие механизмы авторизации?
- Бэкэнд простой, лаконичный и компактный. Меньше строк кода означает меньшую сложность, более быстрое выполнение и (надеюсь 🙂 меньше ошибок и ошибок.
- Вы можете реализовать каждое ограничение авторизации как логический атрибут, свойство или метод модели, в зависимости от того, что вы предпочитаете для каждого правила. Таким образом, вы сможете в любой момент повторно реализовать работу авторизации. Он динамичный, и вы знаете динамические звуки лучше, чем статические 🙂
- Вам не нужно добавлять пользователям дополнительные разрешения или группы.Вы просто программируете ограничения, какими хотите, а затем назначаете их правилам. Готово!
- У вас есть точный контроль над тем, как правила обрабатывают аутентификацию: одно правило может использовать ограничение авторизации, которое использует LDAP, в то время как другие правила вызывают веб-службу (или все, что вы хотите подключить к ограничению авторизации).
- Другие серверы авторизации для каждого объекта создают строку в таблице для каждой комбинации объекта, пользователя и разрешения.Даже с сайтом среднего размера вам будут сниться кошмары о масштабируемости, независимо от того, сколько вы кешируете.
- Другие серверы авторизации должны ВЫБРАТЬ все разрешения, которые есть у пользователя, даже если вам нужно проверить только одно конкретное разрешение, что увеличивает объем памяти.
- Другие серверы авторизации не имеют возможности устанавливать централизованные разрешения, которые необходимы в большинстве проектов.
Требования
django-rules требует правильной установки Django 1.2 (как минимум).
Установка
из Pypi
Просто сделать:
pip установить django-rules
Из источника
Для установки django-rules из исходников:
git clone https://github.com/maraujop/django-rules/ cd django-rules установка python setup.py
Конфигурация
Чтобы django-rules работало, вам нужно подключить его к своему проекту:
- Добавьте его в список из
INSTALLED_APPS
в настройках.py
:
INSTALLED_APPS = ( ... 'django_rules', )
- Добавьте бэкэнд авторизации django-rules в список
AUTHENTICATION_BACKENDS
вsettings.py
:
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', # Бэкэнд аутентификации по умолчанию в Django 'django_rules.backends.ObjectPermissionBackend', )
- Запустите syncdb, чтобы обновить базу данных новыми моделями правил django:
управление питоном.py syncdb
Правила
Правило представляет собой функциональное ограничение авторизации, которое ограничивает действия, которые определенный пользователь может выполнять с определенным объектом (экземпляром Модели).
Каждое определение правила состоит из 6 параметров (3 обязательных и 3 дополнительных):
-
app_name
: имя приложения, к которому применяется правило. -
кодовое имя
: имя правила, уникальное для всех приложений .Это должно быть краткое, но характерное имя. -
модель
: имя модели, связанной с правилом.
-
имя_поля
(необязательно) : имя логического атрибута, свойства или метода модели, реализующей ограничение авторизации. Если не задан, по умолчанию используется кодовое имя -
view_param_pk
(необязательно) : имя параметра представления, которое будет использоваться для получения первичного ключа модели.Он используется в декорированных представлениях для получения фактического экземпляра модели, то есть объекта, для которого будут проверяться права доступа. Если не установлен, по умолчанию используется имя поля первичного ключа в модели. Обратите внимание: если имя параметра представления, содержащего значение первичного ключа объекта, не совпадает с именем первичного ключа модели, в этом параметре должно быть указано новое имя (мы поговорим об этом специальном case в разделе Декораторы). -
описание
(необязательно) : Краткое (максимум 140 символов) описание, объясняющее ожидаемое поведение ограничения авторизации.Несмотря на то, что он не является обязательным, он считается передовой практикой TM и должен использоваться всегда.
Правила должны создаваться для каждого приложения Django. То есть в корневом каталоге приложения Django, в котором вы хотите создать правила, у вас должен быть файл rules.py
, содержащий только объявления тех правил, которые относятся к этому приложению Django.
После того, как вы определили правила в rules.py
, вы захотите их активировать. Для каждого правила, которое вы хотите активировать, должен добавить для него точку регистрации, вызвав django_rules.utils.register
в rules.py
.
Наконец, как только вы правильно настроите rules.py
, вы захотите синхронизировать правила с базой данных. В вашем проекте Django вам нужно будет запустить команду sync_rules
:
python manage.py sync_rules
Эта команда будет искать все ваши файлы rules.py
в вашем INSTALLED_APPS
и синхронизировать последние изменения в базе данных, поэтому вам не нужно запускать syncdb
или перестраивать полную базу данных вообще.
Примеры:
Пример 1. Создание простого и компактного правила для модели Item в приложении Django «доставка»
Представим себе, что в Django-приложении отгрузки
у меня есть следующие models.py
:
из моделей импорта django.db из django.contrib.auth.models импортировать пользователя класс Item (models.Model): поставщик = models.ForeignKey (Пользователь) description = models.CharField (max_length = 50)
Затем представьте, что бизнес-логика в нашем приложении имеет функциональное ограничение авторизации для каждого элемента, например «Товар может быть доставлен только его поставщиком».Теперь, чтобы выполнить ограничение функциональной авторизации, нам нужно только создать простое правило.
Во-первых, давайте начнем с добавления ограничения авторизации в модель Item. Помните, что мы можем использовать метод, логический атрибут или свойство, возвращающее логическое значение. На этот раз мы будем использовать метод:
из моделей импорта django.db из django.contrib.auth.models импортировать пользователя класс Item (models.Model): поставщик = models.ForeignKey (Пользователь) description = models.CharField (max_length = 50) def can_ship (self, user_obj): "" " Проверяет, является ли данный user_obj поставщиком элемента "" " вернуть себя.чтобы всегда добавлять необязательное поле "описание" #, чтобы дать краткое объяснение ожидаемого поведения правила. # Чтобы правила были активными, мы * должны * их зарегистрировать: для правила в rules_list: utils.register (app_name = 'shipping', ** правило)
Наконец, не забудьте синхронизировать правила, чтобы убедиться, что все новые определения, изменения и т. Д. Синхронизируются с базой данных.
python manage.py sync_rules
Пример 2. Создание правила, не соответствующего соглашениям об именах
Представьте, что мы хотели бы назвать наши ограничения авторизации, как мы хотим.Например, давайте изменим предыдущую модель предмета:
.из моделей импорта django.db из django.contrib.auth.models импортировать пользователя класс Item (models.Model): поставщик = models.ForeignKey (Пользователь) description = models.CharField (max_length = 50) def isSameSupplier (self, user_obj): # -> изменение соглашения об именах ограничения авторизации "" " Проверяет, является ли данный user_obj поставщиком элемента "" " вернуть self.supplier == user_obj
Затем нам нужно будет настроить более подробное правило в правилах приложения.py
, используя его дополнительные необязательные поля. На этот раз потребуется только field_name
, но это также хорошая практика TM , чтобы дать краткое описание
:
из django_rules import utils rules_list = [ {'codename': 'can_ship', 'model': 'Item', 'field_name': 'isSameSupplier', 'description': 'Проверяет, является ли данный пользователь поставщиком товара'}, ] # Чтобы правила были активными, мы * должны * их зарегистрировать: для правила в rules_list: утилит.зарегистрироваться (app_name = 'shipping', ** правило)
Опять же, не забудьте синхронизировать правила, чтобы убедиться, что все новые определения, изменения и т. Д. Применяются к базе данных.
python manage.py sync_rules
Использование ваших правил
После того, как вы настроили правило, реализующее ограничение функциональной авторизации, вы можете (и должны 🙂 использовать его в своем приложении. Это действительно просто! В каждом месте, где вы хотите наложить ограничение авторизации на пользователя, вы просто сделаете следующий звонок:
user_obj.has_perm (кодовое имя, model_obj)
Следуя предыдущему примеру 1, представим, что приложение уже работает с данными в базе данных (по крайней мере, один поставщик и один товар, оба с идентификаторами равными 1). Помните, что мы уже реализовали, определили, зарегистрировали и синхронизировали следующее правило:
{'codename': 'can_ship', 'model': 'Item'}
Затем, если бы мы хотели проверить, может ли поставщик отгрузить товар, нам нужно было бы только обеспечить соблюдение правила, выполнив:
поставщик = Поставщик.objects.get (pk = 1) item = Item.objects.get (pk = 1) если supplier.has_perm ('can_ship', item): print 'Ура! Поставщик может отправить товар! :) '
Легко, правда? 🙂
Подробности о внутренней магии django-rules
Обратите внимание, что ниже приводится подробное объяснение того, как протекает вся внутренняя магия в правилах django. Если тебе все равно, пожалуйста, продолжай. Эти детали действительно не нужны, чтобы иметь возможность писать правила и эффективно использовать django-rules. Однако, если вам интересно и вы хотите узнать больше, обратите особое внимание на детали, приведенные ниже.
Вот как складываются все части головоломки:
- Когда вы вызываете
user_obj.has_perm (codename, model_obj)
(в предыдущем примереsupplier.has_perm ('can_ship', item)
), Django передает управление бэкэнду django-rules. - Бэкэнд django-rules затем попытается сопоставить кодовое имя
'can_ship'
иmodel_obj
как модель объекта item.Поскольку в примере 1 мы определили правило{'codename': 'can_ship', 'model': 'Item'}
, совпадение будет. - Затем django-rules проверит, является ли
field_name
атрибутом, свойством или методом, и будет действовать соответственно. Еслиfield_name
— это метод, бэкэнд django-rules проверит, требуется ли ему только один пользовательский параметр или вообще не требуется никаких параметров. В зависимости от требований к параметрам он выполнитmodel_obj.field_name ()
илиmodel_obj.имя_поля (user_obj)
. В нашем примере 1 нам нужен пользовательский параметр, поэтому он выполнитitem.can_ship (supplier)
. - Наконец, если ограничение авторизации, реализованное в
field_name
, имеет значение True или возвращает True, ограничение считается выполненным. В противном случае вы не авторизуетесь.
Подробная информация об использовании методов модели в правилах
Как мы видели, django-rules проверяет, является ли field_name
атрибутом, свойством или методом, и будет действовать соответственно.То есть для очень простых случаев вы можете создавать правила на основе атрибутов и свойств модели. Но в реальных приложениях большую часть времени вы, вероятно, будете устанавливать field_name
для метода в модели.
Важно отметить, что этот метод ограничен наличием только одного параметра (пользовательский объект) или отсутствием параметров вообще. Он не может получать несколько аргументов или аргумент, не являющийся экземпляром User. Хотя это может показаться ограничением, мы не могли придумать вариант использования, в котором остальную необходимую информацию нельзя было бы получить от пользователя или объекта модели.Если вы попали в ситуацию, когда это вас ограничивает, пожалуйста, свяжитесь с нами и объясните свою проблему, чтобы мы могли подумать, как ее обойти! 🙂
Наконец, вам нужно знать кое-что очень важное: метод, назначенный правилу (с этого момента назовем их методы правила ) никогда не должен вызывать какой-либо другой метод . То есть они должны быть самодостаточными. Это сделано для того, чтобы избежать потенциальной бесконечной рекурсии. Представьте себе ситуацию, когда метод правила вызывает другой метод, которого имеет такое же ограничение авторизации , что и предыдущий метод правила.Бум! Вы только что создали бесконечный цикл. Беги, если твоя жизнь тебе дорога! 🙂
Вы можете подумать, что можете это контролировать, но, поверьте мне, это будет очень сложно поддерживать и масштабировать. Не всегда все будет так просто, возможно, вы в конечном итоге вызовете метод, который позже будет изменен и в конечном итоге вызовет вспомогательную функцию, которая запускает тот же цикл авторизации. Да, я знаю. Косвенное обращение — это стерва 🙂 Или, другими словами, «великая сила приходит с большой ответственностью». Так что остерегайтесь бесконечного цикла;)
Декораторы
Если вам так же нравится Python, как и мне, вы полюбите декораторы.Django имеет декоратор permission_required
, поэтому казалось естественным, что django-rules реализовали декоратор object_permission_required
.
Представьте, что для нашего примера 1 у нас есть следующий код в views.py
:
def ship_item (запрос, идентификатор): item = Item.objects.get (pk = id) если request.user.has_perms ('can_ship', item): return HttpResponse ('успех') вернуть HttpResponse ('ошибка')
Мы могли бы легко украсить вид, чтобы сделать метод более компактным и легким для чтения:
из django_rules import object_permission_required @object_permission_required ('can_ship') def ship_item (запрос, идентификатор): return HttpResponse ('Товар успешно отправлен! :)')
Магия декоратора действительно очень крутая.Во-первых, он соответствует правилу и получает из него тип модели. Затем он получает параметр id
из kwargs представления и создает экземпляр объекта Model с item = model.objects.get (pk = id)
. Наконец, он может вызвать для вас request.user.has_perm ('can_ship', item)
и перенаправить на страницу сбоя, если ограничение не выполнено.
Обратите внимание, как мы сохранили имя первичного ключа модели в параметрах представления. Если параметр имеет имя, не совпадающее с именем первичного ключа в модели, помните, что нам придется добавить в правило еще один необязательный параметр.Из раздела Правила:
-
view_param_pk
(необязательно) : имя параметра представления, которое будет использоваться для получения первичного ключа модели. Он используется в декорированных представлениях для получения фактического экземпляра модели. Если не установлен, по умолчанию используется имя поля первичного ключа в модели. Обратите внимание: если имя параметра представления, содержащего значение первичного ключа объекта, не соответствует имени первичного ключа модели, в этом параметре необходимо указать новое имя.
Например, если мы изменим параметр представления:
из django_rules import object_permission_required @object_permission_required ('can_ship') def ship_item (request, my_item_code): # -> изменение наименования параметра в представлении return HttpResponse ('успех')
Нам нужно указать view_param_pk
в определении правила:
rules_list = [ {'codename': 'can_ship', 'model': 'Item', 'view_param_pk': 'my_item_code', 'description': 'Проверяет, является ли данный пользователь поставщиком товара'}, ]
Декоратор object_permission_required
может получать 4 аргумента:
@object_permission_required ('can_ship', return_403 = Истина) @object_permission_required ('can_ship', redirect_url = '/ больше / foo / bar /') @object_permission_required ('can_ship', redirect_field_name = 'myFooField') @object_permission_required ('can_ship', login_url = '/ foo / bar /')
По умолчанию:
-
return_403
имеет значение False. -
redirect_url
устанавливается в пустую строку. -
redirect_field_name
установлен на REDIRECT_FIELD_NAME django.contrib.auth. -
login_url
настроен на.LOGIN_URL
.
Таким образом, если ограничение авторизации не выполнено, декоратор по умолчанию будет перенаправлять на страницу входа в Django-стиле 🙂
Также обратите внимание, что у пары параметров есть специфика. А именно:
- , если
return_403
имеет значение True, он переопределит остальные параметры, и декоратор вернет HttpResponseForbidden. - , если для URL-адреса
redirect_url
задан URL-адрес, он заменит URL-адресlogin_url
.
Наконец, важно отметить сложную деталь, касающуюся использования декоратора для защиты доступа к тем методам, которые не отображаются напрямую как представления, сопоставленные с внешними URL-адресами. Когда метод представления является точкой входа через URL-адреса (то есть, если ваш метод представления сопоставлен непосредственно с одной из записей urls.py
), Django анализирует URL-адрес и передает параметры представлению как kwargs
.Таким образом, если вы хотите использовать декоратор object_permission_required
поверх внутреннего метода (метода, который вызывается внутри одного из этих внешних представлений или где-то еще в вашем коде), вы должны использовать kwargs
при передаче параметров.
Рассмотрим пример:
def item_shipper (запрос, идентификатор): internal_code = 'XXX-' + my_item_code return _ship_item (request, id = internal_code) # вместо выполнения return _ship_item (request, internal_code) @object_permission_required ('can_ship') def _ship_item (запрос, идентификатор) return HttpResponse ('успех')
Централизованные разрешения
django-rules имеет централизованный диспетчер авторизации, который нацелен на очень распространенные потребности в реальных проектах: специальные привилегированные группы, такие как администраторы, сотрудники службы поддержки пользователей и т. Д., у которых есть разрешения на переопределение определенных аспектов ограничений авторизации в приложении. В таких случаях django-rules может позволить вам обойти его систему авторизации по любым причинам.
Для настройки централизованных разрешений вам необходимо установить в настройках вашего проекта переменную CENTRAL_AUTHORIZATIONS
, указывающую на модуль. В этом модуле вам нужно будет определить возвращающую логическое значение функцию с именем central_authorizations
, принимающую ровно два параметра:
-
user_obj
: объект пользователя. -
кодовое имя
: кодовое имя правила, которое мы будем отменять. Очень полезно уточнить разрешения специального пользователя «а-ля ACL».
Обратите внимание: хотя название параметров не имеет значения, порядок имеет значение. Первый параметр получит объект пользователя, а второй параметр — кодовое имя правила.
Эта функция central_authorizations ()
будет вызываться перед любым другим правилом, поэтому вы можете переопределить их все здесь.
Например, в settings.py
вы добавите:
CENTRAL_AUTHORIZATIONS = 'myProjectFoo.utils'
Затем в myProjectFoo в utils.py
вы реализуете функцию central_authorizations ()
с переопределениями для специальных пользователей.
Представьте, что вы хотите предоставить специальный доступ персоналу службы поддержки пользователей, который будет иметь доступ к некоторым личным полям в профиле (например, электронной почте и возрасту), которые обычно скрыты от обычных пользователей приложения.Они предназначены для поддержки пользователей, поэтому они не должны иметь возможности переопределять определенные вещи в приложении. Тем не менее, вы также хотите, чтобы ваши сверхадминистраторы (как правило, разработчики) имели доступ ко всему в приложении, чтобы они могли быстро кодировать и тестировать во время разработки.
В таком случае вы можете написать следующую функцию central_authorizations ()
:
def central_authorizations (user_obj, кодовое имя): "" " Эта функция будет вызываться * перед * любым другим правилом, так что вы можете переопределить все разрешения здесь."" " isAuthorized = Ложь если user_obj.get_profile (). isUberAdmin (): isAuthorized = True elif user_obj.get_profile (). isUserSupport () и кодовое имя в ['can_see_full_profile', 'can_delete_item']: isAuthorized = True возврат разрешен
Как вы понимаете, все, что проверяется в central_authorizations
, является глобальным для всего проекта .
Статус и тестирование
django-rules предназначено для обеспечения безопасности.Таким образом, он был тщательно протестирован. Он поставляется с набором тестов, которые пытаются охватить все доступные функциональные возможности. Однако, если вы столкнетесь с ошибкой или нестандартной ситуацией, не стесняйтесь сообщать об этом через трекер ошибок Github.
Наконец, приложение имеет множество различных исключений, которые будут обеспечивать правильное создание правил. Они также предназначены для защиты вашего приложения от небрежности. Управляйте исключениями с умом, и вы станете счастливым и безопасным программистом, поскольку безопасность защищена от возможной халатности.Вы должны обращаться с ними осторожно.
Тестирование django-rules
Чтобы запустить тесты, войдите в каталог тестов и выполните:
./runtests.py
Он всегда должен говорить ОК. Если нет, то есть сломанный тест, о котором, я надеюсь, вы скоро сообщите 🙂
Нужны еще примеры?
Я изо всех сил пытался объяснить концепцию правил django, но, если вы предпочтете посмотреть больше примеров кода, я уверен, что вы найдете код в тестах весьма полезным 🙂
Дополнительная документация
Если вы хотите узнать, откуда появился весь этот «бэкэнд для объектной аутентификации в Django», вы должны, по крайней мере, прочитать следующие ссылки:
Наконец, я искренне признателен всем, кто вносит свой вклад в замечательную среду разработки Django, а также остальным разработчикам и коммиттерам, которые с их помощью создают правила django.Уважать! 🙂
Добро пожаловать в документацию django-rules-light! — документация django-rules-light 0.1.3
Это простая альтернатива django-rules. Основное отличие в том, что он использует в качестве реестра, который может быть изменен во время выполнения, вместо базы данных модели.
Одна из целей — дать разработчикам внешних приложений возможность создавать правила, зависящие от на нем, позволяя проекту переопределять правила.
Пример your_app / rules_light_registry.py
:
# Каждый может прочитать сообщение в блоге (пока!): rules_light.реестр ['blog.post.read'] = Верно # Требовать аутентификацию для создания сообщения в блоге, используя ярлык: rules_light.registry ['blog.post.create'] = rules_light.is_authenticated def is_staff_or_mine (пользователь, правило, объект): вернуть user.is_staff или obj.author == user # Но другие не должны связываться с моими сообщениями! rules_light.registry ['blog.post.update'] = is_staff_or_mine rules_light.registry ['blog.post.delete'] = is_staff_or_mine
Пример your_app / views.py
:
@rules_light.class_decorator класс PostDetailView (generic.DetailView): model = Опубликовать @ rules_light.class_decorator класс PostCreateView (generic.CreateView): model = Опубликовать @ rules_light.class_decorator класс PostUpdateView (generic.UpdateView): model = Опубликовать @ rules_light.class_decorator класс PostDeleteView (generic.DeleteView): model = Опубликовать
Вы можете прочитать руководство для более.
В чем подвох?
Загвоздка в том, что этот подход не предлагает никаких функций для обеспечения безопасности наборы запросов.
Это означает, что разработчик должен:
- подумайте о безопасности при создании наборов запросов,
- переопределение возможное внешнее приложение ListViews,
Требования
- Python 2.7+ (поддерживается Python 3)
- Джанго 1.4+
Быстрая установка
- Установить модуль:
pip install django-rules-light
, - Добавить в настройки
.INSTALLED_APPS
:rules_light
, - Добавьте в настройки
.MIDDLEWARE_CLASSES
:rules_light.middleware.Middleware
, - Добавьте
urls.py
:rules_light.autodiscover ()
, если у вас естьadmin.autodiscover ()
тоже там (Django <1.7),
Возможно, вы захотите прочитать руководство.
Также есть много документации, от ядра до инструментов, в том числе указатели для отладки, регистрации и проверки вашей безопасности.
Содействующие
Запустите тесты с помощью команды tox.Документированные патчи, проходящие все у тестов больше шансов быть объединенными, подробности см. в руководстве сообщества.
Ресурсы
Вы можете подписаться на список рассылки, задавать вопросы или просто получать информацию о обновления пакета.
В комплекте:
django-rules · PyPI
h2 (# аннотация). django-rulesdjango-rules — это серверная часть авторизации Django, которая предлагает унифицированное управление авторизацией для каждого объекта. Он сильно отличается от других механизмов авторизации тем, что позволяет гибко управлять разрешениями для каждого объекта.
В правилах django каждое правило добавляет ограничение авторизации к данной модели. Ограничение авторизации проверяет, соответствует ли данный пользователь ограничению (например, если у пользователя есть права на выполнение определенного действия над объектом и т. Д.). Ограничение авторизации может быть логическим атрибутом, свойством или методом модели, в зависимости от того, что вы предпочитаете для каждого правила 🙂
h3 (#philosophy). Философия
django-rules стремится создать гибкий и масштабируемый бэкэнд авторизации.Почему это лучше, чем другие механизмы авторизации?
* Бэкэнд простой, лаконичный и компактный. Меньше строк кода означает меньшую сложность, более быстрое выполнение и (надеюсь 🙂 меньше ошибок и ошибок.
* Вы можете реализовать каждое ограничение авторизации как логический атрибут, свойство или метод модели, в зависимости от того, что вы предпочитаете для каждого правила 🙂 Таким образом, вы сможете повторно реализовать работу авторизации в любое время. Он динамический, и вы знаете динамические звуки лучше, чем статические 🙂
* Вам не нужно добавлять дополнительные разрешения или группы для ваших пользователей.Вы просто программируете ограничения, какими хотите, а затем назначаете их правилам. Готово!
* У вас есть точный контроль над тем, как правила обрабатывают аутентификацию: одно правило может использовать ограничение авторизации, которое использует LDAP, в то время как другие правила вызывают веб-службу (или все, что вы хотите подключить к ограничению авторизации).
* Другие механизмы авторизации для каждого объекта создают строку в таблице для каждого объекта, каждого пользователя и каждой комбинации разрешений. Даже с сайтом среднего размера вам будут сниться кошмары о масштабируемости, независимо от того, сколько вы можете кэшировать.
* Другие серверы авторизации должны ВЫБРАТЬ все разрешения, которые есть у пользователя, даже если вам нужно проверить только одно конкретное разрешение, что увеличивает объем памяти.
* Другие серверы авторизации не имеют возможности устанавливать централизованные разрешения, которые являются реальной необходимостью в большинстве проектов.
h3 (# требования). Требования
django-rules требует правильной установки Django 1.2 (как минимум).
h3 (# установка). Установка
h4 (#pypi).Из Pypi
Все просто:
pip install django-rules
h4 (#source). Из источника
Чтобы установить django-rules из источника:
git clone https://github.com/maraujop/django-rules/
cd django-rules
python setup.py install
h3 (# конфигурация). Конфигурация
Чтобы django-rules работало, вы должны подключить его к своему проекту:
* Добавьте его в список INSTALLED_APPS
в settings.py
:
INSTALLED_APPS = (
...
'django_rules',
)
* Добавить сервер авторизации django-rules в список AUTHENTICATION_BACKENDS < / code> в
settings.py
:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', # бэкэнд аутентификации по умолчанию Django
'django_rulesjectbackends.Obackends ,
)
* Запустите syncdb, чтобы обновить базу данных новыми моделями правил django:
python manage.py syncdb
h3 (# правила). Правила
Правило представляет собой функциональное ограничение авторизации, которое ограничивает действия, которые определенный пользователь может выполнять с определенным объектом (экземпляром Модели).
Каждое определение правила состоит из 6 параметров (3 обязательных и 3 необязательных):
* app_name
: имя приложения, к которому применяется правило.
* кодовое имя
: имя правила, _уникальное для всех приложений_.Это должно быть краткое, но характерное имя.
* модель
: имя модели, связанной с правилом.
* field_name
_ (необязательно) _: имя логического атрибута, свойства или метода модели, реализующей ограничение авторизации. Если не установлен, по умолчанию используется значение обязательного поля codename
.
* view_param_pk
_ (необязательно) _: имя параметра представления, которое будет использоваться для получения первичного ключа модели.Он используется в декорированных представлениях для получения фактического экземпляра модели, объекта, для которого будут проверяться права доступа. Если не установлен, по умолчанию используется имя поля первичного ключа в модели. Обратите внимание, что если имя параметра представления, содержащего значение первичного ключа объекта, не совпадает с именем первичного ключа модели, в этом параметре должно быть указано новое имя (мы поговорим об этом специальном case в "разделе о декораторах": # декораторы).
* описание
_ (необязательно) _: краткое (максимум 140 символов) описание, объясняющее ожидаемое поведение ограничения авторизации.и должен использоваться всегда.
Правила должны создаваться для каждого приложения Django. То есть в корневом каталоге приложения Django, в котором вы хотите создавать правила, у вас должен быть файл rules.py
, содержащий только объявления этих правил, специфичных для этого приложения Django.
После того, как вы определили правила в rules.py
, вы захотите их активировать. Для каждого правила, которое вы хотите активировать, вы * должны * добавить для него точку регистрации, вызвав django_rules.utils.register
в rules.py
.
Наконец, как только вы правильно настроите rules.py
, вы захотите синхронизировать правила с базой данных. В своем проекте Django вам нужно будет запустить команду sync_rules
:
python manage.py sync_rules
Эта команда будет искать все ваши rules.py
в вашем INSTALLED_APPS
и будут синхронизировать последние изменения в базе данных, поэтому вам не нужно запускать syncdb
или перестраивать полную базу данных вообще.
h3 (#examples). Примеры:
h4 (# ex1). Пример 1. Создание простого и компактного правила для модели Item в Django-приложении "доставка"
Давайте представим себе, что в Django-приложении shipping
у меня есть следующие модели . py
:
class Item (models.Model):
supplier = models.ForeignKey (User)
description = models.CharField (max_length = 50)
Затем представьте что бизнес-логика в нашем приложении имеет функциональное ограничение авторизации для каждого элемента, например «Товар может быть отправлен только его поставщиком».Теперь, чтобы выполнить ограничение функциональной авторизации, нам нужно только создать простое правило.
Во-первых, давайте начнем с добавления ограничения авторизации в модель Item. Помните, что мы можем использовать метод, логический атрибут или свойство, возвращающее логическое значение. На этот раз мы будем использовать метод:
class Item (models.Model):
supplier = models.ForeignKey (User)
description = models.CharField (max_length = 50)def can_ship (self, user_obj):
"" "
Проверяет, является ли данный user_obj поставщиком элемента
" ""
return self.всегда добавлять необязательное поле «описание»
#, чтобы дать краткое объяснение ожидаемого поведения правила.# Чтобы правила были активными, мы * должны * зарегистрировать их:
для правила в rules_list:
utils.register (app_name = 'shipping', ** rule)
Наконец, не забывайте для синхронизации правил, чтобы убедиться, что все новые определения, изменения и т. д. синхронизируются с базой данных.
python manage.py sync_rules
h4 (# ex2).Пример 2: Создание правила, которое не следует соглашениям об именах
Представьте, что мы хотели бы назвать наши ограничения авторизации, как мы хотим. Например, давайте изменим предыдущую модель Item:
class Item (models.Model):
supplier = models.ForeignKey (User)
description = models.CharField (max_length = 50)def isSameSupplier (self , user_obj): # -> изменение соглашения об именах ограничения авторизации
"" "
Проверяет, является ли данный user_obj поставщиком элемента
" ""
return self.чтобы дать краткоеописание
:
из django_rules import utilsrules_list = [
{'codename': 'can_ship', 'model': 'Item', 'field_name': 'isSameSupplier',
'description': 'Проверяет, является ли данный пользователь поставщиком элемента'},
]# Чтобы правила были активными, мы * должны * зарегистрировать их:
для правила в rules_list:
utils.register (app_name = 'shipping', ** rule)
Опять же, не забудьте синхронизировать правила, чтобы убедиться, что все новые определения, изменения и т. д.применяются к базе данных.
python manage.py sync_rules
h4. Использование ваших правил
После того, как вы настроили правило, реализующее функциональное ограничение авторизации, вы можете (и должны 🙂 использовать его в своем приложении. Это действительно просто! В каждом месте, где вы хотите применить ограничение авторизации для пользователя, вы просто сделаете следующий вызов:
user_obj.has_perm (codename, model_obj)
Следуя предыдущему «примеру 1» : # ex1, давайте представим, что приложение уже работает с данными в базе данных (по крайней мере, один поставщик и один товар, оба с идентификаторами равными 1).Помните, что мы уже реализовали, определили, зарегистрировали и синхронизировали следующее правило:
{'codename': 'can_ship', 'model': 'Item'}
Тогда, если мы хотели проверить, может ли поставщик отгрузить товар, нам нужно было только обеспечить соблюдение правила, выполнив:
supplier = Supplier.objects.get (pk = 1)
item = Item.objects.get (pk = 1)если supplier.has_perm ('can_ship', item):
print 'Ура! Поставщик может отправить товар! :) '
Легко, правда? 🙂
h5.Подробности о внутренней магии django-rules
Обратите внимание, что ниже приводится подробное объяснение того, как протекает вся внутренняя магия в django-rules. Если вам все равно, пожалуйста, двигайтесь дальше. Вам действительно не нужны эти детали, чтобы иметь возможность писать правила и эффективно использовать django-rules. Однако, если вам интересно и вы хотите узнать больше, обратите особое внимание на детали, приведенные ниже.
Вот как собираются все части головоломки:
* Когда вы вызываетеuser_obj.has_perm (codename, model_obj)
(в предыдущем примере,supplier.has_perm ('can_ship', item)
), Django передает управление бэкэнду django-rules.
* Серверная часть django-rules затем попытается сопоставитькодовое имя
с правилом. Обратите внимание, что мы запрашиваем правило сcodename
из'can_ship'
иmodel_obj
как Модель объекта элемента. Поскольку в «Пример 1»: # ex1 мы определили правило{'codename': 'can_ship', 'model': 'Item'}
, совпадение будет.
* Затем django-rules проверит, является лиfield_name
атрибутом, свойством или методом, и будут действовать соответственно. Еслиfield_name
- это метод, бэкэнд django-rules проверит, требуется ли ему только один пользовательский параметр или вообще не требуется никаких параметров. В зависимости от требований к параметрам он выполнитmodel_obj.field_name ()
илиmodel_obj.field_name (user_obj)
. В нашем «примере 1»: # ex1 нам требуется пользовательский параметр, чтобы он выполнял элемент.can_ship (поставщик)
.
* Наконец, если ограничение авторизации, реализованное вfield_name
, имеет значение True или возвращает True, ограничение считается выполненным. В противном случае вы не авторизуетесь.h4. Подробности использования методов модели в правилах
Как мы видели, django-rules проверяет, является ли
field_name
атрибутом, свойством или методом, и будет действовать соответственно. Вы можете создавать правила на основе атрибутов и свойств модели, которые более чем подходят для очень простых случаев, но в большинстве случаев вы будете устанавливатьfield_name
для метода в модели.Важно отметить, что этот метод ограничен наличием только одного параметра (пользовательский объект) или отсутствием параметров вообще. Он не может получать несколько аргументов или аргумент, не являющийся экземпляром User. Хотя это может показаться ограничением, мы не могли придумать вариант использования, в котором остальная необходимая информация не могла бы быть получена от пользователя или объекта модели. Если вы попали в ситуацию, когда это вас ограничивает, пожалуйста, свяжитесь с нами и объясните свою проблему, чтобы мы могли подумать, как ее обойти! 🙂
Наконец, вам нужно знать кое-что очень важное: метод, назначенный правилу (с этого момента давайте называть их _rule methods_) * никогда не должен вызывать какой-либо другой метод *.То есть они должны быть самодостаточными. Это сделано для того, чтобы избежать потенциальной бесконечной рекурсии. Представьте себе ситуацию, когда метод правила вызывает другой метод, который имеет _ такое же_ ограничение авторизации, что и предыдущий метод правила. Бум! Вы только что создали бесконечный цикл. Беги, если твоя жизнь тебе дорога! 🙂
Вы можете подумать, что можете это контролировать, но, поверьте мне, это будет очень сложно поддерживать и масштабировать. Не всегда все будет так просто, возможно, вы в конечном итоге вызовете метод, который позже будет изменен и в конечном итоге вызовет вспомогательную функцию, которая запускает тот же цикл авторизации.Да, я знаю. Косвенное обращение - это стерва 🙂 Или, другими словами, «великая сила приходит с большой ответственностью». Так что остерегайтесь бесконечного цикла;)
h3 (#decorators). Декораторы
Если вам нравится Python так же, как и мне, вы полюбите декораторы. Django имеет декоратор
permission_required
, поэтому казалось естественным, что django-rules реализовали декораторobject_permission_required
.Представьте, что для нашего «Пример 1»: # ex1 у нас есть следующий код в представлениях
.py
:
def ship_item (request, id):
item = Item.objects.get (pk = id)if request.user.has_perms ('can_ship', item):
return HttpResponse ('success')return HttpResponse ('error')
Мы могли бы легко украсить представление, чтобы сделать метод более компактным и легким для чтения:
from django_rules import object_permission_required@object_permission_required ('can_ship')
def ship_item (request, id):
return HttpResponse ('Товар успешно отправлен! :)')
Магия декоратора действительно очень крутая.Во-первых, он соответствует правилу и получает из него тип модели. Затем он получает параметр
id
из kwargs представления и создает экземпляр объекта Model с помощьюitem = model.objects.get (pk = id)
. Наконец, он может вызвать для васrequest.user.has_perm ('can_ship', item)
и перенаправить на страницу сбоя, если ограничение не выполнено.Обратите внимание, как мы сохранили имя первичного ключа модели в параметрах представления.Если параметр имеет имя, не совпадающее с именем первичного ключа в модели, помните, что нам придется добавить еще один необязательный параметр в правило. Из «раздела о правилах:»: # rules
*view_param_pk
_ (необязательно) _: имя параметра представления, которое будет использоваться для получения первичного ключа модели. Он используется в декорированных представлениях для получения фактического экземпляра модели. Если не установлен, по умолчанию используется имя поля первичного ключа в модели. Обратите внимание: если имя параметра представления, содержащего значение первичного ключа объекта, не совпадает с именем первичного ключа модели, в этом параметре необходимо указать новое имя.Например, если мы изменим параметр представления:
из django_rules import object_permission_required@object_permission_required ('can_ship')
def ship_item (request, my_item_code): # -> изменение наименования параметра в представлении
return HttpResponse ('success')
Нам нужно будет указать
view_param_pk
в определении правила:
rules_list = [
{'codename': 'can_ship', 'model': 'Item', 'view_param_pk': 'my_item_code',
'description': 'Проверяет, является ли данный пользователь поставщиком товара'},
]
Декоратор
object_permission_required
может получать 4 аргумента:
@object_permission_required ('can_ship', return_403 = True)
@object_permission_required ('can_ship', redirect_url = '/ more / foo / bar / ')
@object_permission_required (' can_ship ', redirect_field_name =' myFooField ')
@obj ect_permission_required ('can_ship', login_url = '/ foo / bar /')
По умолчанию:
*return_403
имеет значение False.
*redirect_url
- пустая строка.
*redirect_field_name
имеет значение REDIRECT_FIELD_NAME django.contrib.auth.
*login_url
имеет значениеsettings.LOGIN_URL
.Таким образом, если ограничение авторизации не выполняется, декоратор по умолчанию будет перенаправлять на страницу входа в Django-стиле 🙂
Также обратите внимание, что пара параметров имеет специфичность. А именно:
* если дляreturn_403
установлено значение True, он переопределит остальные параметры, и декоратор вернет HttpResponseForbidden.
* если дляredirect_url
задан URL-адрес, он заменит URL-адресlogin_url
.Наконец, важно отметить сложную деталь, касающуюся использования декоратора для защиты доступа тех методов, которые не отображаются напрямую как представления, сопоставленные с внешними URL-адресами. Когда метод представления является точкой входа через URL-адреса (то есть, если ваш метод представления сопоставлен непосредственно с одной из записей
urls.py
), Django анализирует URL-адрес и передает параметры представлению какkwargs
.Таким образом, если вы хотите использовать декораторobject_permission_required
над внутренним методом (методом, который вызывается внутри одного из этих внешних представлений или где-то еще в вашем коде), вы должны использоватьkwargs при передаче параметров.
Давайте посмотрим на пример:
def item_shipper (request, id):
internal_code = 'XXX-' + my_item_code
return _ship_item (request, id = internal_code) # вместо того, чтобы делать return _ship_item (request, internal_code )@object_permission_required ('can_ship')
def _ship_item (request, id)
return HttpResponse ('success')
h3 (#centralizedpermissions).Централизованные разрешения
django-rules имеет централизованный диспетчер авторизации, который нацелен на очень распространенные потребности в реальных проектах: специальные привилегированные группы, такие как администраторы, сотрудники службы поддержки пользователей и т. Д., Которые имеют разрешения на переопределение определенных аспектов ограничения авторизации в приложении. В таких случаях django-rules может позволить вам обойти его систему авторизации по любым причинам.
Для настройки централизованных разрешений вам необходимо установить в настройках вашего проекта переменную
CENTRAL_AUTHORIZATIONS
, указывающую на модуль.В этом модуле вам нужно будет определить возвращающую логическое значение функцию с именемcentral_authorizations
, принимающую ровно два параметра:
*user_obj
: объект пользователя.
*codename
: кодовое имя правила, которое будет отменено. Очень полезно уточнить разрешения специального пользователя «а-ля ACL».
Обратите внимание, что, хотя название параметров не имеет значения, порядок имеет значение. Первый параметр получит объект пользователя, а второй параметр - кодовое имя правила.Эта функция
central_authorizations ()
будет вызываться * перед * любым другим правилом, поэтому вы можете переопределить их все здесь.Например, в
settings.py
вы добавите:
CENTRAL_AUTHORIZATIONS = 'myProjectFoo.utils'
А затем в myProjectFoo в
utils.py
, вы реализуете функциюcentral_authorizations ()
с переопределениями для специальных пользователей.Представьте, что вы хотите предоставить специальный доступ персоналу службы поддержки пользователей, который будет иметь доступ к некоторым личным полям в профиле (например, электронной почте и возрасту), которые обычно скрыты от обычных пользователей приложения. Они предназначены для поддержки пользователей, поэтому они не должны иметь возможности переопределять определенные вещи в приложении. Тем не менее, вы также хотите, чтобы ваши сверхадминистраторы (как правило, разработчики) имели доступ ко всему в приложении, чтобы они могли быстро кодировать и тестировать во время разработки.
В таком случае вы можете написать следующую функцию
central_authorizations ()
:
def central_authorizations (user_obj, codename):
"" "
Эта функция будет вызываться * перед * любое другое правило,
, чтобы вы могли здесь переопределить все разрешения.
"" "
isAuthorized = Falseif user_obj.get_profile (). isUberAdmin ():
isAuthorized = True
elif user_obj.get_profile (). isUserSuserS ) и кодовое имя в ['can_see_full_profile', 'can_delete_item']:
isAuthorized = Truereturn isAuthorized
Как вы понимаете, все, что проверяется в
central_authorizations
, является глобальным для * весь * проект.h3. Статус и тестирование
django-rules предназначено для обеспечения безопасности. Таким образом, он был тщательно протестирован. Он поставляется с набором тестов, которые пытаются охватить все доступные функциональные возможности. Однако, если вы столкнетесь с ошибкой или нестандартной ситуацией, не стесняйтесь сообщать об этом через «трекер ошибок Github»: https: //github.com/maraujop/django-rules/issues.
Наконец, приложение поддерживает множество различных исключений, которые обеспечивают правильное создание правил.Они также предназначены для защиты вашего приложения от небрежности. Управляйте исключениями с умом, и вы станете счастливым и безопасным программистом, поскольку безопасность защищена от возможной халатности. Вы должны обращаться с ними осторожно.
h4. Тестирование django-rules
Чтобы запустить тесты, войдите в каталог тестов и выполните:
./runtests.py
Он всегда должен говорить ОК. Если нет, то есть сломанный тест, о котором, я надеюсь, вы скоро сообщите 🙂
h3.Нужны еще примеры?
Я изо всех сил пытался объяснить концепцию правил django, но, если вы предпочтете посмотреть больше примеров кода, я уверен, что вы найдете «код в тестах»: https: //github.com/ maraujop / django-rules / blob / master / django_rules / tests / test_core.py весьма полезно 🙂
h3. Дополнительная документация
В случае, если вы хотите узнать, откуда появился весь этот «бэкэнд для индивидуальной аутентификации в Django», вы должны, по крайней мере, прочитать следующие ссылки:
* Отличная статья о «бэкэндах для индивидуальных разрешений в Django» : http: // djangoadvent.com / 1.2 / object-permissions / от Флориана Аполлонера
* Также проверьте объяснение изменений, внесенных при исправлении "django ticket # 11010": http: //code.djangoproject.com/ticket/11010Наконец, мой самая искренняя признательность всем, кто вносит свой вклад в прекрасную среду разработки Django, а также остальным разработчикам и коммиттерам, которые создают django-rules с их помощью. Уважать! 🙂
Стиль кодирования | Документация Django
Пожалуйста, соблюдайте стиль отступов, продиктованный в .editorconfig
файл. Мы рекомендуем использовать текстовый редактор с поддержкой EditorConfig, чтобы избежать
проблемы с отступами и пробелами. В файлах Python используются 4 пробела для
отступы и файлы HTML используют 2 пробела.
Если не указано иное, следовать PEP 8 .
Используйте flake8, чтобы проверить наличие проблем в этой области. Обратите внимание, что наш setup.cfg
файл содержит некоторые исключенные файлы (устаревшие модули, которые нас не интересуют
очистка и некоторый сторонний код, который поставщики Django), а также некоторые
исключены ошибки, которые мы не рассматриваем как грубые нарушения.Помни это PEP 8 - это всего лишь руководство, поэтому уважайте стиль окружающего кода как
Главная цель.
Исключением из PEP 8 являются наши правила по длине строк. Не ограничивайте строки
код до 79 символов, если это означает, что код выглядит значительно уродливее или
труднее читать. Мы допускаем до 119 символов, так как это ширина GitHub.
обзор кода; все, что длиннее, требует горизонтальной прокрутки, что делает обзор
труднее. Эта проверка включается при запуске flake8
.Документация,
комментарии и строки документации должны быть заключены в 79 символов, даже если PEP 8 предлагает 72.
Используйте четыре пробела для отступа.
Используйте четыре отступа для подвешивания вместо вертикального выравнивания:
поднять AttributeError ( "Вот многострочное сообщение об ошибке" "сокращено для ясности". )
Вместо:
поднять AttributeError ('Вот многострочное сообщение об ошибке' 'сокращено для ясности.')
Это позволяет лучше использовать пространство и позволяет избежать повторного выравнивания строк, если длина первой строки изменится.
Используйте одинарные кавычки для строк или двойные кавычки, если строка содержит одинарная кавычка. Не тратьте время на несвязанный рефакторинг существующего кода соответствовать этому стилю.
Интерполяция строковой переменной может использовать
% -formatting, f-strings или str.format ()
, в зависимости от ситуации, с целью
максимальная читаемость кода.
Окончательное решение о удобочитаемости остается на усмотрение Слияния. Как руководство, f-строки должны использовать только простые переменные и доступ к свойствам, с предварительное присвоение локальной переменной для более сложных случаев:
# Разрешено f'hello {user} ' f'hello {user.name} ' f'hello {self.user.name} ' # Запрещено f'hello {get_user ()} ' f'вам {user.age * 365,25} дн. ' # Разрешено с присвоением локальной переменной пользователь = get_user () f'hello {user} ' user_days_old = user.age * 365,25 е'вам {user_days_old} дн. '
f-строк не следует использовать для строк, которые могут требовать перевода,
включая сообщения об ошибках и записи в журнал.В общем формате ()
больше
подробный, поэтому предпочтительны другие методы форматирования.
Не тратьте время на несвязанный рефакторинг существующего кода, чтобы скорректировать метод форматирования.
Избегайте использования «мы» в комментариях, например «Зацикливаемся», а не «Зацикливаемся».
Используйте подчеркивания, а не верблюжий регистр, для имен переменных, функций и методов
(т.е. poll.get_unique_voters ()
, а не poll.getUniqueVoters ()
).
Используйте InitialCaps
для имен классов (или для заводских функций, которые
обратные классы).
В строках документации следуйте стилю существующих строк документации и PEP 257 .
В тестах используйте assertRaisesMessage ()
и assertWarnsMessage ()
вместо assertRaises ()
и assertWarns ()
, чтобы вы могли проверить
сообщение об исключении или предупреждении. Используйте assertRaisesRegex ()
и assertWarnsRegex ()
, только если вам нужен регулярный
сопоставление выражений.
Используйте assertIs (…, True / False)
для тестирования
логические значения, а не assertTrue ()
и assertFalse ()
, поэтому вы можете проверить фактическое логическое значение
ценность, а не правдивость выражения.
В тестовых строках документации укажите ожидаемое поведение, которое демонстрирует каждый тест. Не включайте такие преамбулы, как «Проверяет, что» или «Обеспечивает это».
Ссылки на резервные билеты для неясных проблем, когда в билете есть дополнительные подробности, которые сложно описать в документах или комментариях.Включите номер билета в конце такого предложения:
def test_foo (): "" " Строка тестовой документации выглядит так (# 123456). "" " ...
Создание приложения Django с контролем доступа к данным - oso
Почти каждое приложение должно позволять своим пользователям видеть только свои данные. Многие другие приложения идут еще дальше и добавляют дополнительные элементы управления, такие как совместное использование или создание частного и общедоступного контента. Эти концепции становятся все более важными, поскольку конфиденциальность данных постоянно находится в центре обсуждения в технических, деловых и политических кругах.
В этом посте мы рассмотрим, как создать простое социальное приложение, которое позволяет пользователям делиться сообщениями, например Twitter. Мы будем использовать Django, популярный веб-фреймворк Python, который включает ORM и систему шаблонов. В отличие от Twitter, наше приложение будет включать контроль видимости постов. Мы реализуем этот контроль доступа с помощью Oso, механизма политик с открытым исходным кодом, встроенного в ваше приложение. Пакет django-oso позволяет использовать Oso в приложении Django с небольшой настройкой.
В этом руководстве будут рассмотрены:
- Запуск проекта Django
- Создание пользовательской модели пользователя
- Создание моделей и представлений Django для вывода списка и создания сообщений
- Добавление Oso в наше приложение Django для реализации общедоступных и частных сообщений.
Учебное пособие является самодостаточным, но при желании вы можете следить за ним в репозитории на github.
Запуск нашего проекта Django
Для начала нам понадобится Python 3 (минимум 3.6) установлен. Давайте запустим новый каталог для нашего проекта, а также создадим и активируем виртуальную среду.
$ mkdir осо-социальный
$ cd oso-social
$ python -m venv venv
$. Venv / bin / активировать
Теперь давайте установим django
и django-oso
в нашу виртуальную среду.
$ pip install django
$ pip установить django-oso
Django включает инструмент django-admin
, в котором есть команды для создания шаблонов приложений django и их разработки.Мы будем использовать его для запуска нового проекта:
$ django-admin startproject oso_social
Это создаст новый каталог oso_social
в нашем каталоге верхнего уровня:
ls -l oso_social
всего 392
-rwxr-xr-x 1 персонал dhatch 666 3 сентября 16:14 manage.py
drwxr-xr-x 8 dhatch Staff 256 3 сен, 17:55 oso_social
ls -l oso_social / oso_social
всего 32
-rw-r - r-- 1 посох дхатча 0 3 сен 16:14 __init__.ру
-rw-r - r-- 1 посох дхатча 397 3 сен 16:14 asgi.py
-rw-r - r-- 1 посох dhatch 3219 3 сентября 17:55 settings.py
-rw-r - r-- 1 посох дхатча 798 3 сентября 16:44 urls.py
-rw-r - r-- 1 посох дхатча 397 3 сентября 16:14 wsgi.py
Каждый проект Django разбит на несколько приложений. Приложения - это модули Python, которые можно использовать в разных проектах. Модуль oso_social / oso_social
- это модуль проекта, который включает в себя настройки и конфигурацию для нашего проекта oso_social
.
Давайте сейчас создадим приложение, которое будет содержать наши модели и представления базы данных. В каталоге oso_social
:
$ cd oso_social
$ ./manage.py startapp social
ls -l соц.
всего 56
-rw-r - r-- 1 посох dhatch 0 3 сентября 16:14 __init__.py
-rw-r - r-- 1 персонал dhatch 206 3 сен 16:33 admin.py
-rw-r - r-- 1 персонал dhatch 87 3 сентября 16:14 apps.py
-rw-r - r-- 1 посох дхатча 638 3 сен 17:46 models.py
-rw-r - r-- 1 персонал dhatch 60 3 сен 16:14 tests.ру
-rw-r - r-- 1 посох дхатча 394 3 сен 17:52 urls.py
-rw-r - r-- 1 посох дхатча 1312 3 сен 17:59 views.py
Мы только что использовали утилиту manage.py
, которая делает то же самое, что и django-admin, но знает настройки проекта. Это позволяет ему выполнять специфические задачи проекта, такие как операции с базой данных.
Чтобы завершить настройку нашего приложения social
, нам нужно добавить его в файл настроек, чтобы Django узнал об этом. В oso_social / oso_social / settings.py
:
# Найдите этот параметр в файле и добавьте «социальный».
INSTALLED_APPS = [
# ... существующие записи ...
'Социальное',
]
Создание нашей модели пользователя
Сначала мы собираемся создать модель User для представления пользователей в нашем приложении. Эта модель будет использоваться для хранения информации о пользователях в нашей базе данных. Django имеет встроенную систему авторизации, которая обрабатывает такие вещи, как управление паролями, вход в систему, выход из системы и пользовательские сеансы. Пользовательская модель User обеспечивает гибкость для добавления атрибутов позже нашему пользователю.
Давайте создадим его в нашем файле oso_social / social / models.py
. Используйте следующее содержимое:
из моделей импорта django.db
из django.contrib.auth.models импортировать AbstractUser
класс User (AbstractUser):
проходить
Встроенное приложение django.contrib.auth
обеспечивает аутентификацию для проектов Django. Мы будем использовать его, чтобы начать настройку аутентификации. Чтобы создать собственную модель пользователя, мы просто наследуем от AbstractUser
.Мы не определили никаких настраиваемых полей, поэтому тело класса пусто.
Затем мы добавим запись в наш файл настроек в oso_social / oso_social / settings.py
. Файл настроек настраивает проекты и приложения Django в нем. Это стандартный файл Python, в котором каждая запись конфигурации хранится как глобальная переменная. Мы добавим следующую строку:
AUTH_USER_MODEL = 'social.User'
Это указывает приложению django.contrib.auth
использовать модель User
из приложения social
для аутентификации.
Наконец, мы создадим миграцию базы данных. Встроенный в Django инструмент миграции базы данных поддерживает синхронизацию схемы вашей базы данных с моделями, используемыми в вашем приложении. Чтобы выполнить миграцию, запустите:
$ ./manage.py makemigrations соц.
Будет создано oso_social / social / migrations / 0001_initial.py
. Теперь примените эту миграцию к нашей базе данных (поскольку мы не настраивали параметры нашей базы данных, по умолчанию это база данных SQLite).
$./manage.py перенести
Тестирование нашей настройки авторизации: вход в систему
Теперь давайте убедимся, что мы правильно настроили нашу аутентификацию и можем войти в систему. Мы еще не создали никаких представлений, но мы можем использовать встроенный интерфейс администратора Django, чтобы проверить нашу авторизацию.
Сначала добавьте нашу пользовательскую модель пользователя на сайт администратора в oso_social / social / admin.py
:
от администратора импорта django.contrib
из django.contrib.auth.admin импортировать UserAdmin
из .модели импортировать Пользователь
# Зарегистрируйте здесь свои модели.
admin.site.register (Пользователь, UserAdmin)
Затем создайте суперпользователя с помощью команды manage.py
:
$ ./manage.py создает суперпользователя
Вам будет предложено ввести учетные данные, которые вы затем будете использовать для входа на сайт администратора.
Запустим наше приложение:
$ ./manage.py runserver
И посетите http: // localhost: 8000 / admin. Отсюда мы можем войти в систему и получить доступ к интерфейсу администратора.
Создание нашей модели Post
Теперь, когда мы настроили нашу учетную запись, давайте приступим к созданию функции публикации. Наше приложение позволит пользователям создавать новые сообщения и просматривать ленту сообщений. Чтобы поддержать это, мы создадим модель публикации, которая хранит информацию о записях в нашей базе данных.
В oso_social / social / models.py
создайте модель Post
ниже модели User
:
класс Почта (модели.Модель):
ACCESS_PUBLIC = 0
ACCESS_PRIVATE = 1
ACCESS_LEVEL_CHOICES = [
(ACCESS_PUBLIC, "Общедоступно"),
(ACCESS_PRIVATE, "Частный"),
]
содержимое = модели.CharField (max_length = 140)
access_level = models.IntegerField (choices = ACCESS_LEVEL_CHOICES, по умолчанию = ACCESS_PUBLIC)
created_by = models.ForeignKey (Пользователь, on_delete = models.CASCADE)
created_at = models.DateTimeField (auto_now_add = True)
Это определяет класс модели с именем Post
с четырьмя полями: content
, access_level
, created_at
and created_by
. Поле contents
будет хранить сообщение, отправленное пользователем, а created_at
и created_by
сохранят метаданные сообщения.Позже мы будем использовать access_level
, чтобы реализовать видимость сообщений с Oso.
Сохраните этот файл и создайте миграцию, чтобы таблица сохраняла модель Post
в нашей базе данных:
$ ./manage.py makemigrations соц.
Команда makemigrations
проверит модели на соответствие существующим миграциям и при необходимости создаст новые сценарии миграции. Большинство типов изменений в базе данных обнаруживаются автоматически. Примените эту миграцию, как мы делали это раньше, с командой migrate
.
Итак, мы сделали нашу модель Post
. Давайте проверим, что все работает как задумано. Вместо того, чтобы создавать представление, мы будем использовать интерфейс администратора для создания нескольких сообщений. Зарегистрируйте сообщение в интерфейсе администратора, добавив следующее в oso_social / social / admin.py
:
# Добавить импорт поста (в дополнение к пользователю)
из .models import User, Post
# ...
admin.site.register (Сообщение)
Теперь мы можем посетить сайт администратора по адресу: http: // localhost: 8000 / admin /.Доступна модель Post, давайте воспользуемся интерфейсом администратора для создания публикации. Нажмите сообщений , затем Добавить сообщение вверху справа.
Заполните форму, как мы делали выше, и сохраните новую публикацию. Этот пример демонстрирует возможности интерфейса администратора Django. Без специального кода мы смогли протестировать нашу модель и взаимодействовать с ней!
Хорошо, хватит времени в админке. Давайте перейдем к созданию представления фида, которое будут использовать пользователи.С каждой страницей в веб-приложении Django связано представление . Когда пользователь посещает определенный URL-адрес, функция просмотра отвечает за обработку запроса и создание ответа. Напишем простое представление для отображения сообщений.
В oso_social / social / views.py
напишите следующий код:
из django.shortcuts import render
из django.http import HttpResponse
из .models import Post
def list_posts (запрос):
# Не более 10 последних сообщений
posts = Сообщение.objects.all (). order_by ('- created_at') [: 10]
posts_text = ""
для публикации в сообщениях:
posts_text + = f "@ {post.created_by} {post.contents}"
вернуть HttpResponse (posts_text)
list_posts
- это наша функция просмотра. Сначала он использует API Django QuerySet и нашу модель Post
, чтобы получить первые 10 сообщений из базы данных, упорядоченных по последним сообщениям. Затем мы создаем строку для ответа, используя строки формата Python. Наконец, мы возвращаем HttpResponse
, содержащий posts_text
.
Мы написали нашу функцию просмотра, но еще не закончили! Нам все еще нужно указать Django, когда это следует вызывать. Для этого Django использует модули URLconf. Откройте oso_social / oso_social / urls.py
в своем редакторе. Это корневой URLconf. Он указывает, какие функции просмотра запускаются при запросе определенного URL-адреса. Прямо сейчас вы увидите шаблон URL: путь ('admin /', admin.site.urls)
, который управляет сайтом администратора. Добавим еще один паттерн:
# Добавить включить импорт
из джанго.путь импорта URL-адресов, включить
urlpatterns = [
путь ('admin /', admin.site.urls),
путь ('', include ('social.urls'))
]
Это указывает Django использовать файл oso_social / social / urls.py
для разрешения любых URL-адресов, которые не соответствуют admin /
.
Создадим его. В oso_social / social / urls.py
:
из пути импорта django.urls
из .views import list_posts
urlpatterns = [
путь ('', list_posts)
]
Единственный маршрут ( ''
) соответствует странице индекса.Django удаляет начальную косую черту из URL-адреса, поэтому корневая страница соответствует пустой строке. Наша функция list_posts
будет вызываться для обработки запросов на /
.
Попробуем запустить! Если у вас все еще работает ./manage.py runserver
, он должен быть перезагружен автоматически. Если нет, запустите его сейчас и посетите http: // localhost: 8000 /. Вы должны увидеть страницу, подобную приведенной ниже:
Продолжайте и используйте интерфейс администратора, чтобы создать еще несколько сообщений и посмотреть, как все выглядит на нашей новой странице каналов.
Использование шаблонов
Если вы сделали более одного поста, вы, вероятно, заметили, что рендеринг не идеален. Все сообщения отображаются в одной строке. Давайте создадим правильную HTML-страницу для нашего ответа вместо того, чтобы просто отвечать текстом. В этом нам может помочь встроенная система шаблонов Django. Для начала создайте новый файл по пути oso_social / social / templates / social / list.html
.
Добавьте содержимое:
Корм
{% за сообщение в сообщениях%}
@ {{сообщение.created_by.username}} {{post.contents}} {{post.created_at | date: "SHORT_DATETIME_FORMAT"}}
{% endfor%}
Этот HTML-код создан с использованием системы шаблонов Django. Это позволяет нам создавать HTML-страницы, в которых переменные будут заменены нашим кодом представления. Теги {% для сообщения в сообщениях%}
приводят к тому, что переменная шаблона post
назначается каждому элементу из повторяемых сообщений
.Затем мы интерполируем имя пользователя и содержимое, используя {{post.created_by.username}}
и {{post.contents}}
. Дата проходит через фильтр, чтобы правильно отформатировать ее для пользователя. Этот шаблон создаст тег
для каждого сообщения.
Чтобы использовать шаблон, измените нашу функцию list_posts
в oso_social / social / views.py
:
def list_posts (запрос):
# Не более 10 последних сообщений.
posts = Сообщение.objects.all (). order_by ('- created_at') [: 10]
вернуть рендер (запрос, 'social / list.html', {'posts': posts})
Мы использовали функцию рендеринга, которая сообщает Django о необходимости рендеринга шаблона по адресу social / list.html
с контекстом шаблона {'posts': posts}
. Контекст определяет, какие переменные доступны для механизма создания шаблонов. Django будет искать имя шаблона в любом каталоге под названием templates
в каждом приложении.
Теперь наш вид выглядит немного лучше!
Добавление новой формы сообщения
Нам нужно создать еще одно представление: представление «нового сообщения».Это представление позволит пользователю отправить сообщение и сохранит его в нашей базе данных. Начнем с создания шаблона. В oso_social / social / templates / social / new_post.html
:
Новое сообщение
Этот шаблон создает HTML-форму.Мы будем использовать форму Django для замены переменной {{form}}
. {% csrf_token%}
включает маркер для предотвращения атак CSRF (подделка межсайтовых запросов). Эта функция встроена в Django. Мы должны создать новый класс формы для использования с нашим шаблоном. Создайте файл oso_social / social / forms.py
:
из django.forms import ModelForm
из .models import Post
класс PostForm (ModelForm):
класс Мета:
model = Опубликовать
fields = ['содержимое', 'access_level']
Класс PostForm
наследуется от ModelForm
, который создает форму, имеющую входные данные на основе полей модели.Раскрывающийся список access_level
не будет иметь никакого влияния, пока мы не реализуем авторизацию.
Теперь давайте подключим все это к нашей функции просмотра:
# Новый импорт
из django.http import HttpResponseNotAllowed, HttpResponseRedirect
из django.urls импортировать обратный
из .forms import PostForm
# ...
def new_post (запрос):
если request.method == 'POST':
# Эта ветка запускается, когда пользователь отправляет форму.
# Создать экземпляр формы с отправленными данными.form = PostForm (request.POST)
# Преобразовать форму в экземпляр модели. commit = Ложь откладывает
# сохранение в базу данных.
post = form.save (фиксация = False)
# Сделать пользователя, вошедшего в систему, создателем сообщения.
post.created_by = request.user
# Сохранить пост в базе.
post.save ()
# Повторно перейти к списку сообщений.
вернуть HttpResponseRedirect (обратный ('индекс'))
elif request.method == 'ПОЛУЧИТЬ':
# GET вычисляется при загрузке формы.form = PostForm ()
# Визуализировать представление с формой для заполнения пользователем.
возврат рендера (запрос, 'social / new_post.html', {'form': form})
еще:
return HttpResponseNotAllowed (['GET', 'POST'])
Наконец, мы обновим наш URLconf, чтобы включить новое представление сообщений:
из пути импорта django.urls
из .views import list_posts, new_post
urlpatterns = [
путь ('', list_posts, name = 'index'),
путь ('новый /', новый_пост, имя = 'новый_пост'),
]
Аргумент name
для path
позволяет нам искать путь url по имени, которое мы используем как в наших шаблонах ( {% url 'new_post'%}
), так и для просмотра reverse ('index')
.
Давайте добавим кнопку на страницу индекса для перехода на страницу нового сообщения в oso_social / social / templates / social / list.html
:
Новое сообщение
Добавление страниц входа и выхода
Затем нам нужно добавить функцию входа в наше приложение, чтобы пользователи, у которых нет доступа к интерфейсу администратора, могли его использовать. У встроенного приложения аутентификации Django есть представления, которые могут управлять входом в систему и выходом из нее.
Чтобы воспользоваться ими, нам нужно добавить записи в наш URLconf в oso_social / social / urls.py
:
из django.contrib.auth импортировать просмотры как auth_views
urlpatterns = [
# ...
путь ('логин /', auth_views.LoginView.as_view (template_name = 'social / login.html'), name = 'login'),
путь ('logout /', auth_views.LogoutView.as_view (), name = 'logout'),
]
Мы должны предоставить шаблон для представления входа в систему, и мы также захотим добавить кнопки входа и выхода из системы на каждой странице. Мы воспользуемся преимуществами системы наследования шаблонов Django, чтобы создать базовый шаблон, содержащий эти кнопки.Создайте файл oso_social / social / templates / social / base.html
:
{% block title%} oso-social {% endblock%}
{% if user.is_authenticated%}
Добро пожаловать, @ {{user.username}}.
Выйти
{% endif%}
Войти
{% содержимого блока%}
{% endblock%}
Устанавливает кнопку выхода и входа в систему, а также область содержимого {% block contents%}
, которую могут заполнять другие шаблоны.
Обновите наш шаблон list.html
:
{% extends 'social / base.html'%}
{% содержимого блока%}
Корм
{% за сообщение в сообщениях%}
@ {{post.created_by.username}} {{post.contents}} {{post.created_at | date: "SHORT_DATETIME_FORMAT"}}
{% endfor%}
Новое сообщение
{% endblock%}
и new_post.html
:
{% extends 'social / base.html '%}
{% содержимого блока%}
Новое сообщение
{% endblock%}
Тег {% extends%}
указывает, что этот шаблон наследуется от базового шаблона и заменяет содержимое между {% block contents%}
и {% endblock%}
в базовый.
Теперь создадим наш шаблон входа в систему! В oso_social / social / templates / social / login.html
:
{% extends 'social / base.html'%}
{% содержимого блока%}
Войти
{% endblock%}
Мы добавим в наш файл настроек следующие записи, которые необходимы для обеспечения работы этих встроенных представлений:
LOGIN_REDIRECT_URL = 'индекс'
LOGIN_URL = 'войти'
LOGOUT_REDIRECT_URL = 'индекс'
Наконец, мы можем добавить декоратор @login_required
в наше представление new_post
в oso_social / social / views.py
, который перенаправит пользователя на страницу входа в систему, если они попытаются создать сообщение перед входом в систему:
из django.contrib.auth.decorators import login_required
@login_required
def new_post (запрос):
# ...
Использование Oso для скрытия личных сообщений
Теперь, когда у нас есть основы, давайте дадим пользователям возможность создавать личные сообщения. Мы будем использовать для этого Осо.
Напомним, что наше определение модели для Post
включало поле с именем access_level
:
класс Post (модели.Модель):
ACCESS_PUBLIC = 0
ACCESS_PRIVATE = 1
ACCESS_LEVEL_CHOICES = [
(ACCESS_PUBLIC, "Общедоступно"),
(ACCESS_PRIVATE, "Частный"),
]
access_level = models.IntegerField (choices = ACCESS_LEVEL_CHOICES, по умолчанию = ACCESS_PUBLIC)
В этом целочисленном поле хранятся два варианта: ACCESS_PUBLIC
или ACCESS_PRIVATE
. Значения выбора: 0
и 1
соответственно, но пользовательская метка «Public»
или «Private»
.Подробнее о вариантах см. Здесь.
Теперь давайте добавим django-oso
в наше приложение и настроим нашу политику публикации. Сначала добавьте django_oso
в список установленных приложений.
В oso_social / oso_social / settings.py
добавьте django_oso
в список из INSTALLED_APPS:
INSTALLED_APPS = [
# ...,
'django_oso',
]
django-oso предоставляет функцию авторизации
, которая будет оценивать политику управления доступом для данного актера, действия и ресурса.Мы будем использовать эту функцию для фильтрации сообщений из списка. В oso_social / social / views.py
:
# ...
из django.core.exceptions import PermissionDenied
из django_oso.auth авторизовать импорт
def list_posts (запрос):
# Не более 10 последних сообщений.
posts = Post.objects.all (). order_by ('- created_at') [: 10]
авторизованные_посты = []
для публикации в сообщениях:
пытаться:
авторизовать (запрос, сообщение, действие = "просмотр")
авторизованный_posts.append (сообщение)
кроме PermissionDenied:
Продолжать
возврат рендера (запрос, 'social / list.html ', {' posts ': authorized_posts})
Для каждого сообщения, полученного из базы данных, мы вызываем и авторизуем
. Сообщения, которые не могут быть просмотрены пользователем, вызывают исключение PermissionDenied
. Они отфильтровываются из списка authorized_posts
, который возвращается пользователю.
Напоследок напишем нашу политику. Создайте файл с именем oso_social / social / policy / post.polar
:
# Разрешить кому угодно просматривать любые общедоступные сообщения.allow (_actor, "view", post: social :: Post), если
post.access_level = social :: Post.ACCESS_PUBLIC;
# Разрешить пользователю просматривать свои личные сообщения.
allow (актер: social :: User, "view", post: social :: Post), если
post.access_level = social :: Post.ACCESS_PRIVATE и
post.created_by = актер;
Каждая политика Oso состоит из правил, которые начинаются с заголовка правила, содержащего предикат ( allow (субъект, действие, ресурс),
в данном случае) и тело правила. Функция авторизации
запросит политику разрешить
правил.Если санкционируемый субъект, действие и ресурс соответствуют заголовку правила (часть правила до , если
), тело будет оценено, чтобы определить, успешен ли запрос.
В этой политике у нас есть два правила. Первое правило гласит, что любой субъект может выполнить действие «просмотр»
над сообщением
, имеющим уровень общего доступа. В заголовке правила мы используем _actor
для идентификации актера, что указывает на то, что переменная не будет использоваться и будет соответствовать любому значению.Действие должно соответствовать буквальному значению "view"
, а сообщение должно быть экземпляром модели Django social.Post
(синтаксис : TYPE_NAME
указывает на ограничение типа, а подключаемый модуль django-oso
делает Django модели, доступные в политике под их
).
У второго правила такая же голова, но мы требуем, чтобы актер был моделью social.User
. Это правило будет соответствовать только зарегистрированным пользователям (незарегистрированные пользователи имеют тип django :: contrib :: auth :: AnonymousUser
).Затем мы проверяем, является ли уровень доступа частным, и что сообщение создано субъектом, пытающимся получить к нему доступ. Это кодирует правило «актеры могут получить доступ к своим личным сообщениям».
Теперь давайте протестируем наше приложение. Создайте несколько личных сообщений и убедитесь, что вы их видите. Затем создайте нового пользователя через интерфейс администратора (http: // localhost: 8000 / admin / social / user /). Выйдите из системы и снова войдите с этим пользователем и убедитесь, что личные сообщения не отображаются!
Расширение вашей политики и правил авторизации с помощью Oso
Приведенная выше политика очень проста, но демонстрирует способность политик Oso напрямую взаимодействовать с объектами из вашего приложения.Язык политик, называемый Polar, - это декларативный язык программирования, предназначенный для выразительного описания правил авторизации.
Поскольку мы стандартизировали наш интерфейс в логику авторизации с помощью функции authorize
, мы можем легко вносить изменения, чтобы контролировать, какие сообщения могут просматривать пользователи. Допустим, у нас появился новый тип пользователей - модератор. Они могут просматривать все сообщения, но другие пользователи могут просматривать только сообщения, одобренные модератором. Приведенная ниже политика реализует эту функцию:
# Модераторы могут просматривать любые сообщения.allow (user: social :: User, "view", _: social :: Post), если
user.is_moderator;
# Модераторы могут проводить модерацию любого сообщения.
allow (user: social :: User, "умеренный", _: social :: Post), если
user.is_moderator;
# Разрешить кому угодно просматривать любые общедоступные сообщения.
allow (_actor, "view", post: social :: Post), если
# NEW - Публичные сообщения должны быть одобрены модераторами.
post.approved и
post.access_level = social :: Post.ACCESS_PUBLIC;
# Разрешить пользователю просматривать свои личные сообщения.
allow (актер: social :: User, "view", post: social :: Post), если
сообщение.access_level = social :: Post.ACCESS_PRIVATE и
post.created_by = актер;
Это изменение политики, а также несколько небольших изменений в наших моделях - все, что нам нужно, чтобы настроить наше приложение для поддержки модераторов.
В этом руководстве мы увидели, как создать приложение Django и использовать модели, представления и шаблоны для создания простого клона Twitter. Приложение позволяет пользователям создавать новые сообщения и просматривать свои личные сообщения и все другие общедоступные сообщения.
Затем мы использовали Oso для реализации контроля видимости для сообщений и показали, как политики Oso допускают расширение по мере роста возможностей приложения и правил авторизации.
Чтобы узнать больше о политиках Oso, ознакомьтесь с нашим кратким руководством. Посетите нашу документацию, чтобы получить более подробную информацию о библиотеке django-oso
, которую мы использовали в этом посте, или, если у вас есть какие-либо другие технические вопросы или отзывы, присоединяйтесь к нам в Slack или открывайте проблему.
Как реализовать несколько типов пользователей с помощью Django
Это очень распространенная проблема, с которой сталкиваются многие разработчики на ранних этапах разработки нового проекта, и это тоже вопрос, который мне часто задают. Итак, я подумал о том, чтобы поделиться своим опытом с предыдущими проектами Django о том, как обрабатывать несколько типов пользователей.
Я пробовал много разных стратегий. В этом уроке я поделюсь своими мыслями по этой конкретной теме и поделюсь с вы выбираете стратегии, которые лучше всего работали для меня, в зависимости от требований проекта.
Многие проектные решения зависят от требований и бизнес-модели разрабатываемого приложения. я постараюсь охватить как можно больше различных сценариев. Внимательно прочтите и выберите лучший вариант для себя.
Если вы лучше учитесь на примерах или спешите прямо сейчас, переходите к практическому примеру.В противном случае продолжайте читать.
Практические правила
То, что вы собираетесь читать дальше, не высечено на камне. Это всего лишь несколько общих рекомендаций, которые подходят для большинства случаев. Если у вас есть веская причина или несоблюдение этих рекомендаций приведет к лучшему дизайну приложения, перейдите вперед и нарушайте «правила»!
1. Независимо от того, какую стратегию вы выбираете или какова ваша бизнес-модель, всегда используйте одну и только одну модель Django для обработки аутентификации.
У вас все еще может быть несколько типов пользователей, но, вообще говоря, хранить информацию для аутентификации - плохая идея. по нескольким моделям / таблицам.Рассматривайте эту модель как учетную запись , а не как пользователя . Это означает, что всем пользователям нужен аккаунт для входа.
Бизнес-логика будет реализована по-другому, поэтому нет необходимости распределять имя пользователя / пароль между несколькими таблицы. В конце концов, все учетные записи должны иметь много общих ресурсов, таких как вход, выход, сброс пароля, пароль. изменять.
2. Никогда не используйте встроенную модель пользователя Django напрямую, даже если встроенная реализация пользователя Django удовлетворяет всем требованиям вашего приложения.
По крайней мере, расширьте модель AbstractUser
и включите AUTH_USER_MODEL
в своих настройках.
Требования всегда меняются. В будущем вам может потребоваться настроить модель User и переключить AUTH_USER_MODEL
после того, как ваше приложение запущено в производство, будет очень болезненно. В основном потому, что вам нужно будет обновить все внешние ключи для модели User. Это можно сделать, но эта простая мера (которая, честно говоря, не требует усилий в
начало проекта) избавит вас от головной боли в будущем.
Это даст вам свободу добавлять собственные методы в модель пользователя без необходимости полагаться на модель OneToOne или необходимо реализовать абстрактную модель.
Кроме того, во встроенной модели Django есть некоторые старые дизайнерские решения (которые сохраняются в таком виде из-за обратного совместимость), которые несовместимы со многими требованиями приложений, такими как поле электронной почты, допускающее значение NULL, электронная почта поле не является уникальным, поле имени пользователя чувствительно к регистру, что означает, что у вас может быть пользователь с именем пользователя ana и еще один с Ana , полями имени и фамилии, которые не являются «международными» (некоторые приложения лучше иметь, например, «полное имя» и «псевдоним»).
Стратегии
То, как вы собираетесь реализовать несколько типов пользователей, зависит от требований вашего приложения. Ниже несколько вопросы, которые вы должны задать себе:
- Сколько информации, относящейся к каждому типу пользователей, вам необходимо поддерживать?
- Могут ли пользователи иметь более одной роли в приложении? Например. может ли пользователь быть учеником и учителем одновременно?
- Сколько разных типов пользователей потребуется приложению для управления?
Очень распространенный случай - иметь обычного пользователя и пользователя с правами администратора.В этом случае вы можете использовать встроенный флаг is_staff
чтобы отличать обычных пользователей от администраторов. На самом деле встроенная модель User имеет два похожих поля: is_staff
и is_superuser
. Эти флаги используются в приложении Django Admin, флаг is_staff
указывает, может ли пользователь войти в систему.
страницы администратора Django. Теперь то, что этот пользователь может или не может делать, определяется структурой разрешений (где вы можете
добавить определенные разрешения для данного пользователя, e.г. может создавать / обновлять пользователей, но не может удалять пользователей). is_superuser
flag - это дополнительный флаг для назначения всех разрешений без необходимости добавлять по одному. Итак, как видите,
разрешения управляются на двух разных уровнях.
Если вам необходимо сохранить дополнительную информацию, относящуюся к пользователям, вы должны спросить себя, есть ли эта конкретная информация актуально для всех пользователей или только для определенного типа пользователей. Например, «номер студента» может быть только актуально для пользователей Student.В таких случаях лучше добавлять модель профиля через взаимно однозначное отношение. Сейчас же, если дополнительная информация актуальна для всех пользователей (например, изображение аватара), лучше всего добавить дополнительное поле непосредственно в Модель User.
Если пользователи в вашем приложении могут одновременно выполнять несколько ролей (например, быть учеником и учителем), или ваша
приложение будет иметь только несколько типов пользователей, вы можете контролировать эту информацию в центральной модели пользователя и создавать
такие флаги, как is_student
и is_teacher
:
класс Пользователь (AbstractUser):
is_student = модели.BooleanField ('статус студента', по умолчанию = False)
is_teacher = models.BooleanField ('статус учителя', по умолчанию = False)
Это, пожалуй, самый простой способ работать с несколькими типами пользователей.
Другой вариант: если пользователи могут брать на себя только одну роль, у вас может быть поле выбора, как в примере ниже:
класс Пользователь (AbstractUser):
USER_TYPE_CHOICES = (
(1, 'студент'),
(2, 'учитель'),
(3, «секретарь»),
(4, 'руководитель'),
(5, 'админ'),
)
user_type = модели.PositiveSmallIntegerField (choices = USER_TYPE_CHOICES)
Таким образом, у вас есть центральная точка для проверки типа пользователя. Обычно лучше работает использование логических флагов!
Если ваше приложение обрабатывает много типов пользователей, и пользователи могут принимать на себя несколько ролей, можно создать дополнительную таблицу. и создать отношения "многие ко многим":
класс Роль (models.Model):
'' '
Записи ролей управляются системой,
автоматически создается посредством миграции данных Django.'' '
СТУДЕНТ = 1
УЧИТЕЛЬ = 2
СЕКРЕТАРЬ = 3
НАБЛЮДАТЕЛЬ = 4
ADMIN = 5
ROLE_CHOICES = (
(СТУДЕНТ, 'студент'),
(УЧИТЕЛЬ, 'учитель'),
(СЕКРЕТАРЬ, «секретарь»),
(НАЧАЛЬНИК, «руководитель»),
(АДМИНИСТРАТОР, 'админ'),
)
id = models.PositiveSmallIntegerField (choices = ROLE_CHOICES, primary_key = True)
def __str __ (сам):
вернуть self.get_id_display ()
класс User (AbstractUser):
role = models.ManyToManyField (Role)
Было бы бессмысленно создавать роли программно, потому что они очень привязаны к бизнес-логике.если ты нужно гибкое управление разрешениями, лучше использовать структуру разрешений Django, где вы можете создавать группы и определите конкретные разрешения.
В этом случае я создал несколько констант внутри ролевой модели, чтобы вы могли определять поведение в приложении, используя эти
постоянные значения, например , если роль == Role.ADMIN:
.
Стоит отметить, что эта стратегия не очень распространена. Сначала оцените возможность создания настраиваемых групп разрешений не было бы лучше, потому что Django уже предоставляет несколько платных услуг для такого рода вещей.
Выбор правильной стратегии
Я создал блок-схему ниже, чтобы помочь вам решить, какая стратегия вам подходит. Оранжевые бриллианты - это решение точки; вопросы, на которые нужно ответить, чтобы определить наиболее подходящий вариант. Синие прямоугольники - это действия, которые вы нужно будет выполнять исходя из ваших решений.
Эта блок-схема также является хорошим инструментом, чтобы напомнить вам о том, что важно учитывать при разработке вашего применение.
Аутентификация и авторизация
Управление несколькими типами пользователей или ролями в веб-приложении сводится к управлению разрешениями.Логические флаги вроде is_student
или is_staff
обычно работают как фиксированные и предварительно определенные правила разрешений, которые включены в
исходный код вашего приложения.
Прежде чем мы перейдем к реализации, важно выделить эти две концепции:
- Аутентификация (Вход)
- Авторизация (Разрешение)
Аутентификация - это процесс проверки того, является ли человек тем, кем он себя называет. На практике это процесс проверки логина и пароля (логина).
Авторизация - это процесс проверки того, что этому конкретному лицу разрешено делать в приложении. Этого можно добиться с помощью декораторов представлений, встроенной инфраструктуры разрешений Django или какого-либо стороннего приложения, например django-guardian или джанго-правила.
Обработка аутентификации с помощью Django довольно проста, поскольку она более стандартизирована. Кроме того, независимо от того, что пользователь может в приложении процесс проверки их учетных данных должен быть примерно таким же, не так ли? Это обычно случай в большинстве приложений Django.Дело в том, что большинство форм аутентификации Django охватывает аспекты, связанные с как аутентификация, так и авторизация. При этом авторизация всегда происходит после аутентификации .
В зависимости от потребностей вашего приложения, для всех типов пользователей может быть достаточно одной формы аутентификации и представления. Но в в некоторых случаях вам все равно потребуется реализовать различные формы для авторизации определенных пользователей для доступа к определенным модулям или страницы вашего приложения.
Теперь, обрабатывая авторизацию, т.е.д., то, что пользователи могут или не могут делать, является основной проблемой реализации нескольких типы пользователей. Это немного сложнее, потому что это можно сделать на разных уровнях:
- Это можно сделать на уровне модуля или приложения, например, Django Admin; только сотрудники могут получить доступ к страницам под
/ admin /
. - В одном модуле или приложении только определенные типы пользователей могут видеть и взаимодействовать с некоторыми конкретными страницами.
- Управление разрешениями в том же модуле, где некоторые пользователи могут выполнять только определенные действия (например, создавать или обновлять объекты), где другие пользователи также могут удалять объекты.
- Существуют также разрешения на уровне объекта, когда только пользователь, создавший объект, может взаимодействовать с ним. Например на Facebook, только вы можете редактировать свои собственные сообщения (возможно, какой-нибудь суперпользователь / сотрудник также может взаимодействовать с ним, но с точки зрения бизнес-логики посты принадлежат авторам).
В следующем разделе мы рассмотрим несколько реальных вариантов использования. Вы также найдете полный исходный код, чтобы вы могли исследуйте дальше или даже используйте код в качестве отправной точки для своей реализации.
Практический пример
Я планировал создать простой пример, чтобы проиллюстрировать один случай, но в итоге мне слишком понравилось реализация. Итак, я создал что-то более сложное (которое я могу использовать в будущих примерах). Хорошо то, что теперь у вас есть рабочий пример, который вы можете изучить или повторно использовать некоторые части реализации.
В любом случае, в этом примере используются Python 3.6, Django 2.0 и Bootstrap 4.
Я назвал проект «Школа Джанго», и это приложение, в котором учителя могут создавать викторины, а учащиеся могут подписывать вверх и выберите их интересы.Приложение покажет студентам викторины, связанные с их интересами.
Итак, вкратце: учителя создают викторины и просматривают результаты пройденных викторин.
Студенты могут отвечать на викторины.
Вы можете просматривать просмотры в режиме реального времени, используя этот URL: django-school.vitorfs.com.
Модели
Вот как я представил модели, относящиеся к типам пользователей:
models.py
из django.contrib.auth.models import AbstractUser
из моделей импорта django.db
класс User (AbstractUser):
is_student = models.BooleanField (по умолчанию = False)
is_teacher = models.BooleanField (по умолчанию = False)
класс Студент (модели.Модель):
user = models.OneToOneField (Пользователь, on_delete = models.CASCADE, primary_key = True)
quizzes = models.ManyToManyField (Викторина, через = 'TakenQuiz')
Interest = models.ManyToManyField (Subject, related_name = 'Interest_students')
Обратите внимание, что я не создавал модель с именем Teacher
.Пока в этом нет необходимости. Потому что Студент
класс
например, просто используется для хранения информации, относящейся к студентам.
Мы можем различать пользователей и узнать, является ли данный пользователь студентом или нет, проверяя is_student
флаг.
На данный момент вы можете игнорировать викторины
и интересов
поля. Это информация, связанная с бизнес-логикой
приложение.
Регистрация / создание пользователя
В этом случае я создал одно представление и форму регистрации для каждого случая.
urls.py
из django.urls import include, path
from classroom.views import classroom, студенты, учителя
urlpatterns = [
путь ('', включить ('classroom.urls')),
путь ('accounts /', include ('django.contrib.auth.urls')),
путь ('accounts / signup /', classroom.SignUpView.as_view (), name = 'signup'),
путь ('accounts / signup / student /', student.StudentSignUpView.as_view (), name = 'student_signup'),
путь ('учетные записи / регистрация / учитель /', TeacherSignUpView.as_view (), name = 'teacher_signup'),
]
В модуле urls.py вы можете увидеть, что у меня есть три регистрационных адреса. Первый спрашивает пользователя, хотят ли они зарегистрироваться. как студент или преподаватель:
Эти кнопки представляют собой просто ссылки, которые ведут пользователя либо к StudentSignUpView
, либо к TeacherSignUpView
.
Регистрация студентов
Ниже представлена только базовая обработка представления с использованием общего представления на основе классов CreateView
и наиболее важная часть:
Форма StudentSignUpForm
.
просмотров / student.py
из django.contrib.auth импортировать логин
из django.shortcuts перенаправление импорта
из django.views.generic import CreateView
from ..forms import StudentSignUpForm
from ..models import User
класс StudentSignUpView (CreateView):
model = Пользователь
form_class = StudentSignUpForm
template_name = 'registration / signup_form.html'
def get_context_data (self, ** kwargs):
kwargs ['user_type'] = 'студент'
вернуть super ().get_context_data (** kwargs)
def form_valid (self, form):
пользователь = form.save ()
логин (self.request, пользователь)
return redirect ('student: quiz_list')
Теперь определение формы, которая отвечает за тяжелую работу:
forms.py
из форм импорта django
из django.contrib.auth.forms импортировать UserCreationForm
из транзакции импорта django.db
from classroom.models импортировать Студент, Тема, Пользователь
класс StudentSignUpForm (UserCreationForm):
интересы = формы.ModelMultipleChoiceField (
queryset = Subject.objects.all (),
widget = forms.CheckboxSelectMultiple,
required = True
)
класс Meta (UserCreationForm.Meta):
model = Пользователь
@ transaction.atomic
def сохранить (себя):
user = super (). save (фиксация = ложь)
user.is_student = Верно
user.save ()
студент = Student.objects.create (пользователь = пользователь)
student.interests.add (* self.cleaned_data.get ('интересы'))
return user
В качестве базы я использовал встроенную UserCreationForm
, которая определяет поля username
и password
.Внутри сохранения
я устанавливаю флаг is_student
на True
. И затем после этого я создаю профиль Student
для хранения
Дополнительная информация. Наконец, объявление об интересах учащегося, сохраненное в модели профиля. Обратите внимание, что метод сохранения
украшен транзакцией . атомарный
, чтобы убедиться, что эти три операции выполняются в одной транзакции базы данных.
и избежать несоответствия данных в случае ошибки.
учитель зарегистрироваться
Регистрация учителей очень похожа, но проще:
просмотров / учителей.py
из django.contrib.auth импортировать логин
из django.shortcuts перенаправление импорта
из django.views.generic import CreateView
класс TeacherSignUpView (CreateView):
model = Пользователь
form_class = TeacherSignUpForm
template_name = 'registration / signup_form.html'
def get_context_data (self, ** kwargs):
kwargs ['user_type'] = 'учитель'
вернуть super (). get_context_data (** kwargs)
def form_valid (self, form):
пользователь = form.save ()
логин (сам.запрос, пользователь)
возврат перенаправления ('учителя: quiz_change_list')
forms.py
из django.contrib.auth.forms импортировать UserCreationForm
from classroom.models import User
класс TeacherSignUpForm (UserCreationForm):
класс Meta (UserCreationForm.Meta):
model = Пользователь
def save (self, commit = True):
user = super (). save (фиксация = ложь)
user.is_teacher = Верно
если совершить:
user.save ()
return user
Здесь просто нужно переключить флаг is_teacher
на True
.Шаблон выглядит так:
Защита взглядов
Простой способ защитить ваши представления - создать декораторы представлений и применить их к определенным представлениям.
В приведенных ниже примерах я использовал встроенный user_passes_test
для создания двух настраиваемых декораторов. Один, чтобы проверить, если
пользователь - студент, а второй - чтобы проверить, является ли пользователь учителем.
decorators.py
из импорта django.contrib.auth REDIRECT_FIELD_NAME
из джанго.contrib.auth.decorators import user_passes_test
def student_required (function = None, redirect_field_name = REDIRECT_FIELD_NAME, login_url = 'login'):
'' '
Декоратор для представлений, который проверяет, что вошедший в систему пользователь является студентом,
при необходимости перенаправляет на страницу авторизации.
'' '
actual_decorator = user_passes_test (
лямбда u: u.is_active и u.is_student,
login_url = login_url,
redirect_field_name = redirect_field_name
)
если функция:
return actual_decorator (функция)
вернуть actual_decorator
def teacher_required (function = None, redirect_field_name = REDIRECT_FIELD_NAME, login_url = 'login'):
'' '
Декоратор для представлений, который проверяет, что вошедший в систему пользователь является учителем,
при необходимости перенаправляет на страницу авторизации.'' '
actual_decorator = user_passes_test (
лямбда u: u.is_active и u.is_teacher,
login_url = login_url,
redirect_field_name = redirect_field_name
)
если функция:
return actual_decorator (функция)
return actual_decorator
В основном эти функции student_required
и teacher_required
представляют собой фрагменты кода, которые будут выполняться каждый раз
представление выполнено.
Если мы хотим, чтобы представление было доступно только учащимся, мы должны использовать его следующим образом:
просмотров / учеников.py
из django.contrib.auth.decorators import login_required
из django.shortcuts импортировать get_object_or_404, отобразить
from ..decorators import student_required
from ..models import Quiz
@login_required
@student_required # <- сюда!
def take_quiz (запрос, pk):
quiz = get_object_or_404 (Тест, pk = pk)
студент = request.user.student
# тело представления ...
вернуть визуализацию (запрос, 'classroom / student / take_quiz_form.html', {
'quiz': викторина,
"вопрос": вопрос,
'form': форма,
'прогресс': прогресс
})
В приведенном выше примере показано использование двух декораторов в представлении на основе функций.В этом примере вид take_quiz
защищен от пользователей, которые не вошли в систему, и от пользователей, не являющихся студентами.
Теперь, если вы используете представления на основе классов, вот как мы его используем:
просмотров / student.py
из django.utils.decorators import method_decorator
из django.contrib.auth.decorators import login_required
from ..decorators import student_required
@method_decorator ([login_required, student_required], name = 'dispatch')
класс StudentInterestsView (UpdateView):
model = Студент
form_class = StudentInterestsForm
template_name = 'класс / студенты / интерес_форм.html '
success_url = reverse_lazy ('студенты: список_вопросов')
def get_object (сам):
вернуть self.request.user.student
def form_valid (self, form):
messages.success (self.request, 'Интересы успешно обновлены!')
return super (). form_valid (form)
Нам нужен дополнительный импорт method_decorator
. Затем мы передаем список декораторов представления. Это почти то же самое.
Здесь происходит следующее: если пользователь не авторизован, он попадает на страницу входа.
Проверка типа пользователя
Чтобы проверить тип пользователя, который хочет добавить настраиваемое поведение в шаблон или где-либо еще, это просто вопрос выполнения
простой , если
.
Например, на двух первых снимках экрана вы можете видеть, что цвет фона студенческой области зеленый, а цвет фона для учителя фиолетовый. Для этого у меня есть два набора CSS, затем я применяю их к шаблону HTML. динамически:
шаблонов / base.html
{%, если пользователь.is_authenticated и user.is_teacher%}
{% еще %}
{% endif%}
Вы можете применить ту же логику для представлений, к которым имеют доступ и учащиеся, и преподаватели, но они могут видеть разные Ресурсы. Например, меню другое, или учителя могут видеть определенную кнопку. Затем вы можете построить эту логику в шаблон.Только не забудьте защитить сам вид с помощью декораторов! В противном случае использование может подделать URL-адрес и получить доступ к ресурсам, к которым у них не должно быть доступа.
Выводы
Короче говоря, у вас всегда будет одна модель User для обработки аутентификации. Не распространяйте имя пользователя и пароли по
несколько моделей. Обычно расширяется модель User по умолчанию и добавляются логические флаги, такие как is_student
и is_staff
работают в большинстве случаев. Разрешениями можно управлять на более высоком уровне с помощью декораторов представлений.Если вам нужна гибкость
управление разрешениями (нет четких ролей между пользователями или множества конкретных ролей), вам нужно будет использовать Django's
структура разрешений или сторонняя библиотека.
Если вы хотите увидеть этот пример проекта вживую, перейдите на django-school.vitorfs.com. Исходный код можно найти в репозитории на GitHub.
Я потратил некоторое время на этот пример, чтобы он хорошо выглядел. Если вам интересно узнать больше о Django, это проект - хорошая возможность погрузиться глубже. В частности, вы можете получить представление о том, как писать собственные формы. и наборы форм, как работать с представлениями на основе общих классов и как использовать некоторые компоненты Bootstrap 4 для создания Шаблоны Django.
Если у вас есть вопросы, не стесняйтесь их задавать в комментариях ниже!
.