$ sudo apt-get install --no-install-recommends xserver-xorg x11-xserver-utils xinit openbox chromium-browser
/etc/xdg/openbox/autostart
:# Отключаем скринсейвер и режим сна для монитора
xset s off
xset s noblank
xset -dpms
# Разрешаем убийство процесса иксов по нажатию Ctrl + Alt + Backspace
# Чтобы снова запустить: $ sudo startx -- -nocursor
setxkbmap -option terminate:ctrl_alt_bksp
# Старт браузера Chromium в режиме киоска
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.config/chromium/'Local State'
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/; s/"exit_type":"[^"]\+"/"exit_type":"Normal"/' ~/.config/chromium/Default/Preferences
chromium-browser --disable-infobars -incognito --noerrdialogs --kiosk 'http://127.0.0.1:8000/'
~/.bash_profile
(для автозапуска иксов при перезагрузке):[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && startx -- -nocursor
Ctrl + Alt + F2
и переходим в консоль. Обратно в браузер — Ctrl + Alt + F1
. Чтобы убить процесс иксов — Ctrl + Alt + Backspace
.В случае зависания браузера и невозможности сделать ребут RPi (всякое бывает), можно подключиться по SSH, убить процесс браузера и запустить его заново на мониторе, который подключен к HDMI:$ export DISPLAY=:0 $ sudo chromium-browser -incognito --noerrdialogs --disable-infobars --kiosk http://127.0.0.1:8000/
Помню, задал этот вопрос на Skype-интервью — HR замялась, видимо такое не объясняется в методичке по найму... В результате, не сошлись по графику работы, но вопрос про «коммерческие проекты» был пройден обычными ссылками на поддерживаемые проекты на GitHub (как личные, так и контрибьючные).
gettext()
.Даже строгий договор и прочие юридические штуки — не могут обезопасить проект от такого произвола. Нет, с точки зрения «кто виноват и сколько он за это заплатит» — всё хорошо.. но оставшейся команде или новым разработчикам — от этого не холодно не жарко — им же всё исправлять. Это я уже из своего опыта разгребания подобного кейса говорю :)
Нужно разбираться в коде и быть профессионалом на своём месте, чтобы совершать такой контроль — не спорю, но... а как по-другому, если потеря данных и/или функциональности сайта — может стоить гораздо дороже, чем з/п человека в штате (на аутсорсе), который будет следить за качеством кода и бить по рукам всех, кто будет пытаться испортить его?
@register.generator('examle:example:image_800x800')
class OverlayImage(ImageSpec):
format = 'JPEG'
options = {'quality': 100}
@property
def processors(self):
model, field_name = get_field_info(self.source)
return [
ResizeToFill(800, 800),
TextOverlayProcessor(text=model.description)
]
image_800x800
:image_800x800 = ImageSpecField(
source='image',
id='tours:tours:image_800x800'
)
Выражаю благодарность пользователю javedimka за участие и помощь в пояснении многих моментов. Так как я не люблю вопросы без ответов в интернете, то напишу его тут (благо, что javedimka разрешил).
# ./app/utils.py
def send_mail_to_admin(obj):
hotels = obj.hotels.all().order_by('cost')
message = 'Тур ID ' + obj.pk + '\n'
message += 'Страна: ' + obj.country_name + ' Город: ' + obj.country_name + '\n'
message += 'Отели: \n'
for hotel in hotels:
message += hotel.name + ' ' + hotel.star + ' ' + hotel.cost + ' руб. \n'
send_mail(
'From Admin',
message,
'no-reply@example.com',
['admin@example.com'],
fail_silently=False,
)
# ./app/admin.py
from .utils import send_mail_to_admin
class ToursAdmin(admin.ModelAdmin):
exclude = ('created_at',)
list_display = ('country',)
ordering = ('created_at',)
inlines = (HotelsInline,)
def response_add(self, request, obj, post_url_continue=None):
send_mail_to_admin(obj)
return super().response_add(request, obj, post_url_continue)
value
для каждого из option
. Иначе, какое значение вы будете передавать при submit
формы? Сделать это проще простого:<select id="select">
<option value="Вася">Вася</option>
<option value="Петя">Петя</option>
<option value="Терпила">Терпила</option>
</select>
const select = document.querySelector('#select').getElementsByTagName('option');
for (let i = 0; i < select.length; i++) {
if (select[i].value === 'Терпила') select[i].selected = true;
}
value
в option
, то условие в цикле нужно переписать на вот это:for (let i = 0; i < select.length; i++) {
if (select[i].textContent === 'Терпила') select[i].selected = true;
// Или вот на это, если там присутствует html, например:
// if (select[i].innerHTML === '<p>Терпила</p>') select[i].selected = true;
}
annotate
, чтобы дубликаты не выводились:# ./visa/views.py
from django.db.models import Avg
class TouristVisaSupportView(View):
...
def get(self, request):
form = self.form_class()
form.fields['citizenship'].queryset = Citizenship.objects.filter(citizenshipinvitationprice__type=1).annotate(Avg('id'))
return render(request, self.template_name, {'form': form})
<input type="hidden" name="_token" value="{{ csrf_token() }}">
{{ csrf_field() }}