TL; DR: нормально поместить функцию в класс модели, однако, если вы хотите защищенного входа в систему, вам нужно будет передать информацию для входа в систему в токене, используя что-то вроде Flask-Login (я не уверен, что эквивалентно расширение для django).
Размещение функции внутри класса - это хорошо, однако это не очень безопасно для входа в систему, поэтому я бы посоветовал следовать руководству по реализации расширения безопасного входа в систему.
Например, в одном из моих проектов функция представлений для страницы входа в систему выглядит следующим образом:
@user.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(next=request.args.get('next'))
if form.validate_on_submit():
u = User.find_by_identity(request.form.get('identity'))
if u and u.authenticated(password=request.form.get('password')):
if login_user(u, remember=True) and u.is_active():
# Handle optionally redirecting to the next URL safely.
next_url = request.form.get('next')
if next_url:
return redirect(safe_next_url(next_url))
return redirect(url_for('user.settings'))
else:
flash('Identity or password is incorrect.', 'error')
return render_template('user/login.html', form=form)
Обратите внимание, что u.authenticated
- это функция в моем классе модели пользователя, которая проверяет хэш пароля пользователя. правильно:
def authenticated(self, with_password=True, password=''):
#Ensure a user is authenticated, and optionally check their password.
if with_password:
return check_password_hash(self.password, password)
return True
// std::back_inserter usage ( std::inserter for map )
std::copy( source.begin(), source.end(), std::back_inserter( container ) );
-
// mem_fun and bind usage (but boost better)
std::some_algorithm(..., std::mem_fun( func ) );
не очень полезный, но мощный: проверка
отсортирована в контейнере
std::adjacent_find( container.begin(), container.end(), greater<Container::value_type>() ) == container.end()
, также приведены примеры с тобой и прямо сейчас.
Мне больше всего нравится копирование контейнеров на выход: И копирование входного потока в контейнер.
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
int main()
{
std::vector<int> data;
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(data)
);
std::copy(data.begin(),data.end(),
std::ostream_iterator<int>(std::cout,"\n")
);
}
Следующая идиома необходима для фактического удаления элементов, удаленных с помощью remove ()
или remove_if ()
:
vector<int> v;
...
v.erase(remove(v.begin(), v.end(), 42), v.end());
remove ()
и remove_if ()
просто перемещают не удаленные элементы вперед и сообщают, где заканчивается новый диапазон - они этого не делают (и могут 't) удалите их, потому что они могут работать с любым произвольным диапазоном итераторов, а не только с контейнером.
Что мне больше всего нравится, так это использовать bind1st / bind2nd / mem_fun для сортировки делегатов.
// will call a->func(v[i])
for_each(v.begin(), v.end(), bind1st(mem_fun(&A::func), &a));
// will call w[i]->func(72)
for_each(w.begin(), w.end(), bind2nd(mem_fun(&A::func), 72));
Использование boost bind и функции намного лучше, но это впечатляет, что можно сделать только с помощью STL.
copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(),
ostream_iterator<char>(cout));
Другая часто используемая идиома - инициализация контейнера из массива:
#include <map>
using namespace std;
int main() {
typedef std::map<char,int> LUT;
typedef LUT::value_type LUT_item_t;
const LUT_item_t items[] = { LUT_item_t('b',1),
LUT_item_t('a',5)
};
LUT my_map(items, items + sizeof items/sizeof items[0]);
return 0;
}
Но если вы хотите чистой магии, посмотрите на Boost Lambda Library ;) Пример:
vector<int*> vp(10);
sort(vp.begin(), vp.end(), *_1 > *_2);
Для вашего второго примера используйте тип значения:
#
Copy a map to a vector:
typedef map<T1, T2> MyMap;
MyMap myMap;
vector< MyMap::value_type > myVec(myMap.begin(), myMap.end());
Мне нравится этот зацикливание по каждой строке в файле. Из колонки Эндрю Кенига в «Докторе Доббсе».
for (string s; getline(stream,s); ) {
// Process line
}