Задать вопрос
  • Почему не подгружаются статические файлы в режиме разработки?

    syschel
    @syschel
    freelance/python/django/backend
    Почему не подгружаются статические файлы в режиме разработки?
    Потому-что в режиме runserver, джанго отдаёт статику из папок(их несколько может быть) указанных в константе STATICFILES_DIRS. И работает это в режиме дебага. То есть когда у вас DEBUG = True.
    На продакшене же, на рабочем сервере, у вас во первых должен быть включён DEBUG = False. А пути до статики вы указываете не в самой джанге, а в вашем nginx/apache веб-сервере. И там хоть какой путь может быть, хоть даже не в папке проекта. Главное указать в настройках веб-сервера, слушать путь который вы указали в константе STATIC_URL. Ибо джанго будет отдавать пути до файлов в ответах сервера, которые вы указываете в константах MEDIA_URL и STATIC_URL.

    Выше вам подсказал Александр, для чего нужны эти две папки. Для выполнения консольной команды collectstatic, после которой вся статика из STATICFILES_DIRS, самой джангой соберётся и переместится в папку STATIC_ROOT. По этому и ругается, что дескать "папка разработки" и "папка итоговой сборки", не может быть одной и той же.

    Как вариант, костыльный, если вы всё-равно не используете collectstatic, для сборки статики, то можете в settings.py, закомментировать строку с STATIC_ROOT или STATICFILES_DIRS. А в файл urls.py, добавить строки:

    from django.conf import settings
    from django.conf.urls.static import static
    
    if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
        urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

    Но это, имхо, именно костыль.
    Ответ написан
    Комментировать
  • Как проверить что пользователь это автор в Django?

    syschel
    @syschel
    freelance/python/django/backend
    Проверяем авторизирован пользователь? Если да, то отдаём только те посты, где он является автором.
    Если же пользователь не авторизирован, то отдаём всё остальное по вашим фильтрам
    class PostListView(ListMixin, ListView):model = Post
        ordering = '-pub_date'
        paginate_by = 10
        template_name = 'blog/index.html'
    
        def get_queryset(self):
            queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
            
            if self.request.user.is_authenticated  # Проверяем пользователь авторизованный или нет
                return queryset.filter(author=self.request.user) 
            return queryset.filter(category__is_published=True, 
                                              is_published=True,
                                              pub_date__lte=timezone.now())


    get_object_or_404 - Достаёт только один объект, вы же хотите получить список, судя по названию класса. При этом если вдруг не найдётся ни одной записи, то будет вызвана принудительная ошибка 404. То есть далее ваш код выполняться не будет.

    Если же нужно проверить есть ли у авторизированного хоть один пост, в противном случае считаем его не "автором", то так:

    def get_queryset(self):
            queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
            
            if self.request.user.is_authenticated  # Проверяем пользователь авторизованный или нет
                queryset =  queryset.filter(author=self.request.user) 
            if not queryset:  # либо можно так - if not len(queryset): 
                queryset = queryset.filter(category__is_published=True, 
                                                  is_published=True,
                                                  pub_date__lte=timezone.now())
            return queryset


    Но если у вас понятие "автор" определяется не только наличием созданных им постов. То лучше вносить в модель пользователей статус автор он или нет.
    class User(models.Model):
        ....
        is_author = models.BooleanField(default=False)
        ...

    И тогда проверка уже будет такой

    ...
        def get_queryset(self):
            queryset = super().get_queryset().all( ).annotate(comment_count=Count("comments"))
            
            if self.request.user.is_authenticated and self.request.user.is_author:
                return queryset.filter(author=self.request.user) 
            return queryset.filter(category__is_published=True, 
                                              is_published=True,
                                              pub_date__lte=timezone.now())

    Естественно, если пользователь автор, но постов создать не успел, то ему вернётся пустой список.
    Ответ написан
    2 комментария
  • Bitbucket фсе, блокирует российские IP?

    syschel
    @syschel
    freelance/python/django/backend
    Если не брать VPN(через него нормально), то помогла установка ключей доступа.
    1. В папке /home/{USER}/.ssh
    выполнил команду ssh-keygen -t rsa -b 2048
    Взятую от сюда: https://support.atlassian.com/bitbucket-cloud/docs...
    Ключ именовал по дефолту, на своё название, чёт ругалось в будущем
    2. Беру получившийся ключ командой: cat id_rsa.pub
    3. Перехожу в настройки доступа по ssh в аккаунте битбакета: https://bitbucket.org/account/settings/ssh-keys/
    Нажимаю добавить и вставляю ключ, выведенный в п.2 в консоль

    Далее, если ранее ссылки были HTTP, то надо их поменять на SHH. Как указано в инструкции по первой ссылке:
    HTTPS
    https://<repo_owner>@bitbucket.org/<accountname>/<reponame>.git
    SSH
    git@bitbucket.org:<repo_owner>/<reponame>.git
    or 
    ssh://git@bitbucket.org/<repo_owner>/<reponame>.git

    Менял в конфиге гита, в файле .git/config, в переменной url

    Как под виндовс генерить ключи, гуглите уже сами.

    З.Ы. Обновить доступ к репозитарию, можно командой
    git remote set-url origin git@bitbucket.org/<repo_owner>/<reponame>.git

    З.З.Ы. Уточнение от Антон Кащеев по типам выпускаемых ключей, от 20.06.2023: https://bitbucket.org/blog/ssh-host-key-changes
    Ответ написан
    3 комментария
  • Стоит ли использовать Django при разработке относительно небольшого сайта?

    syschel
    @syschel
    freelance/python/django/backend
    php - голый, без фреймворков будет "лучше" и "проще". Не придётся искать VPS для хостинга, или хостинг площадки с поддержкой питона. Не будет столько же бубнов с залитием и запуском. Для описанного функционала, даже фреймворк не нужен, всё уложится в пол сотни пхп строк.
    Если же вопрос строится из того, что питон и джанго это единственные тебе знакомые язык с фреймворком. То бери их, потому что знакомое проще и быстрее.
    Если же волнуешься за место на хостинге, то сейчас уже не те времена, когда хостинг 100мб в месяц стоил около 1000 рублей. Сейчас гигами продают, за доллар. Тут больше вопрос с поддержкой питона, так как под него не каждый хостер продаст требуемое, а ВПС как правило дороже и "сложнее" для новичка.
    Ответ написан
    Комментировать
  • Как понять, что ты готов к трудоустройству?

    syschel
    @syschel
    freelance/python/django/backend
    Сходите на собеседования, тогда и узнаете. Только в ИТ порой уровень очень сильно расплывчат от специфики компании и фронту работ. Где-то знания ваши могут оценить как уверенный мид, почти сеньёр. В другой компании скажут, что вы даже на среднего джуна не дотягиваете, с теми же знаниями.
    По этому, я бы попробовал походить по собеседованиям джунов/стажеров. Поработать месяца 3-4. А там уже будет проще и будет понимание своего уровня и главное "как и что нужно".
    Ответ написан
    Комментировать
  • Как Url-шаблон передать в DetailView?

    syschel
    @syschel
    freelance/python/django/backend
    как мне pk передать в views.py используя DetailView&

    Оно само ловит pk/id, передавать не нужно, главное эту переменную указать в адресе.

    django 3+

    У вас кажется древняя документация по джанге, сейчас так урлы не строят.
    Правильнее было бы так:
    urlpatterns = [
        path('', views.index, name='index'),
        path('books/', views.BookListView.as_view(), name='books'),
        path('book/<int:pk>/', views.BookDetailView.as_view(), ),
        path('authors/', views.AuthorListView.as_view(), name='authors'),
        path('author/<int:pk>/', views.AuthorDetailView.as_view(), name='author-detail')
    ]
    Ответ написан
    2 комментария
  • Как задать новое значение циклу на Python?

    syschel
    @syschel
    freelance/python/django/backend
    Такое?
    for num in range(1, 9+1):
        print("num: {}, num/2: {}, num/3: {}".format(num, num/2, num/3))


    num: 1, num/2: 0.5, num/3: 0.3333333333333333
    num: 2, num/2: 1.0, num/3: 0.6666666666666666
    num: 3, num/2: 1.5, num/3: 1.0
    num: 4, num/2: 2.0, num/3: 1.3333333333333333
    num: 5, num/2: 2.5, num/3: 1.6666666666666667
    num: 6, num/2: 3.0, num/3: 2.0
    num: 7, num/2: 3.5, num/3: 2.3333333333333335
    num: 8, num/2: 4.0, num/3: 2.6666666666666665
    num: 9, num/2: 4.5, num/3: 3.0
    Ответ написан
    7 комментариев
  • Как отправить переменную в template Django?

    syschel
    @syschel
    freelance/python/django/backend
    Два варианта вижу я:
    1. Работать через context_processors. Создать свой класс процессора и добавить его в сеттинги. Тогда он будет на любой странице срабатывать. Внутри уже этого процессора обрабатывать урлы и так далее.
    context_processors.py
    from django.core.context_processors import request
    def sidebar(request):
        return {'context_auto': ...}

    settings.py
    TEMPLATES = [
        { ...,
            'OPTIONS': {
                'context_processors': [
                            "context_processors.sidebar",
                ],
            },
        },
    ]

    В любом шаблоне теперь будет доступна переменная "context_auto" вызывать можно {{ context_auto }} или передавать.

    2. Другой вариант. Использовать Inclusion tags, а не{% include "sidebar.html" %} и через него выводить свой sidebar. То есть вы создаёте функцию, в которой прописываете логику и загрузку sidebar.html а на странице уже инклудите именно функцию, а не html
    templatetags/inclusion_tag.py
    @register.inclusion_tag('sidebar.html', takes_context=True)
    def sidebar(context):
        return ...

    В main.html пишем
    {% sidebar %}
    Ответ написан
  • На чем написан сайт https://mstagency.ru?

    syschel
    @syschel
    freelance/python/django/backend
    Nuxt.js — Универсальные приложения на Vue.js
    https://ru.nuxtjs.org/
    Nuxt.js — это минималистичный фреймворк для создания приложений на Vue.js с серверным рендерингом, разделением кода, горячей заменой ...
    Ответ написан
    Комментировать
  • Как правильно спроектировать базу данных для сайта?

    syschel
    @syschel
    freelance/python/django/backend
    Мне кажется вы немного перемудрили, излишне усложнив.
    Смотря на ваше "меню", как вижу таблицы в БД я:
    + pages = id, url(ЧПУ, если выводить в адресной строке хотим не ИД), title(заголовок), text(тело страницы, то есть текст)
    + news = id, url, date, title, short_text(этот текст выводим в списке новостей, он короткий), text(это уже на странице новости), image(картинка новости)
    + photo_category(если нужны альбомы для набора фотографий) = id, title, text(описание альбома), image(превьюшка альбома)
    + photos = id, name(если нужно название или описание), image(путь до файла), category(ссылка на photo_category, если нужны альбомы, иначе поле не создаём)
    + videos = id, video(ссылка на видео файл)
    + document_category = id, name
    + documents = id, category(ссылка на document_category ), ISBN(какой-то идентификатор документа вне бд), created(дата_тайм создания), update(дата_тайм обновления/изменения)

    Если изменений у документов несколько, в разные периоды, то я бы выносил поле update в отдельную таблицу
    + document_modifed = id, document(ссылка на документ), date, comment(комментарий иб изменениях, если он нужен)

    Ещё можно было бы добавить пользователей, пускай не на уровне пользователей сайта, а просто как список, то добавил бы. Чтобы указывать автора документа, автора изменений документа(если это нужно отслеживать).

    Поля category в таблице photos и document_category , у меня подразумевают, что категория у них может быть выбрана одна из, а не множество из. Если нужно именно множественный, то да, создавать отдельную таблицу и указывать там связи
    Я сделал специально независимые таблицы "категорий", так как скорее всего они и будут независимыми, не пересекающимися. Тогда при создании под объекта, можно выбирать из списка категории только его типа, а не копаться во всех категориях скопом. То есть, создавая запись об документе, не надо выбирать среди "фоточки с корпаратива 2018", "протяжные валы", "зарплаты", "отмечаем юбилей", "отчёты".
    Ответ написан
    Комментировать
  • Как войти в админку на кмс jQuery?

    syschel
    @syschel
    freelance/python/django/backend
    jQuery это не CMS, это даже не фреймворк, это библиотек для облегчения работы с JavaScript. У библиотеки нет никакой админки. Она может использоваться в какой-то из CMS и даже во фреймворке, но не является ни тем ни другим.
    Путь к админ панелям на всех ЦМС разный, как правило есть небольшой набор "стандартных" путей и чаще всего он встречается у разных сайтов, но не всегда. К примеру /admin или /administrator. Не редко владельцы своих сайтов, изменяют стандартный путь на свой или вообще отключают доступ к панели администратора.
    Ответ написан
    Комментировать
  • Какой класс дать блоку?

    syschel
    @syschel
    freelance/python/django/backend
    Может всётаки разговор не про класс, а название тега, отвечающего за блок доп информации, по правилам HTML5?
    <aside>
    Ответ написан
  • Разница между сайтом "блог" и "новостным" сайтом?

    syschel
    @syschel
    freelance/python/django/backend
    Задался таким вопросом. В чем отличие между сайтом "блог" и "новостным" сайтом, в техническом плане?
    Ни чем. Это как в столярном деле, "чем отличается шкаф от тумбочки технически?", ответ "ни чем, только размерами". Что у блога, что у новостного сайта, функционал может быть идентичным. Как и блог может быть в десятки раз монструознее новостного сайта, при этом допустимо и обратное. Всё зависит от конкретных задач. Новостной сайт может быть и из одной страницы, где всего пяток новостей, меняющихся раз в месяц. Как и блог состоящий из сотней разделов и "модулей", не завязанных чисто на "текстовом" контенте.

    Какие модули, библиотеки используются для создания сайта новостей в Django?
    Какие модули, библиотеки используются для создания сайта блог в Django?
    Если вас интересуют "модули и библиотеки", то это нужно смотреть в сторону готовых ЦМС. Джанго это всётаки фреймворк, где подразумевается собственноручное написание с использованием функционала фреймворка, а не использование сторонних "модулей и библиотек".

    За googlи! - гуглил четкого ответа нет!
    Зачем Django когда есть Wordpress - ответ: потому что Python!
    Если не корректно задан вопрос - буду рад если кто то поправит, но суть вопроса думаю все равно понятна.
    Если у вас "академический" интерес к Джанге, то советую на ближайшие пол года забыть о таких вещах как "готовые модули и библиотеки". Ладно там Pillow для работой с картинками или requests для работы с запросами к другим сервисам. Но вот функционал "блога"/"новостей", это всё делается инструментами джанги. Авторизация, админка, контент, поиск и так далее.

    исторически сложилось что Python изучается как основной язык программирования, да и задача не состоит в быстром запуске проекта, основной упор нацелен на его качестве, к слову "WStanley", а что касается удобства на Django, уже появился Wagtail CMS
    Ответ выше, для изучения питона и его фреймворка Джанго, не нужны вам готовые цмс, библиотеки и модули. Изучите внимательно фреймворк, он всё реализует своим функционалом.
    Ответ написан
    Комментировать
  • Карьера в webdev?

    syschel
    @syschel
    freelance/python/django/backend
    Без живого проекта, сложно развиваться. На голой теории из книжек и курсов, вы многое не удержите в голове.
    По моему опыту, большинство "стартапов" прогорает, даже если их делают профессиональные программисты с 10+ лет стажа. Так как для успешности проекта, нужен ещё и маркетинг (продвижение продукта), да и кучу других сопутствующих вещей.
    Но вам как новичку, это полезно в первую очередь для нарабатывания практики на живом проекте. При этом вы зацепляете кучу смежных вещей, которые вам на курсах могут не давать. К примеру "как разместить в интернете, а не на локальном ПК" или "как добавить счётчики/метрики от сторонних сервисов(гугл/яндекс/...)". Научитесь работать с АПИ разных систем. Научитесь выполнять, пускай и своё, но ТехЗадание.
    У новичков порой самая большая проблема, как заметил я, даже по себе. Это не законченные задачи при возникновении трудностей. К примеру начал делать регистрацию пользователей, не смог разобраться с сессиями и забросил это, переключившись на каталог. А там уже и в каталоге, к примеру с фильтрами товаров, уперевшись в проблему, бросает и начинает делать что-то другое.
    Ответ написан
    Комментировать
  • Какие есть сервисы контроля удаленных сотрудников?

    syschel
    @syschel
    freelance/python/django/backend
    На том же UpWork`e есть ТаймТрекер, софтинка которая при почасовой оплате, в произвольный период из 10 минут, делает скриншот экрана и записывает активность мышки и клавиатуры. Можно включить и снимок с вебкамеры, но то на любителя. Если активности не было больше 15-20 минут, таймер останавливается. Оплата начисляется по часам в трекере. Скриншоты можно удалять, но удалится и те 10 минут где он был сделан. Для фриланса, для фриланса с почасовой оплатой - удобно. Для фикспрайсов смысла в ней нету. Неудобно когда задачи не строятся на активности у ПеКа (к примеру надо на бумажке порисовать, или сделать звонки, или посидеть и подумать или дождаться выполнения долгой задачи). Но конкретно у апворка, можно добавлять мануальное время (время вне трекера).

    З.Ы. Работаю несколько лет через трекер и нечего зазорного, постыдного, угнетающего или "рабского" в этом не вижу.
    Ответ написан
    1 комментарий
  • Как получить посты за текущую неделю django queryset?

    syschel
    @syschel
    freelance/python/django/backend
    Можно запросить данные по номеру недели week и iso_year
    import datetime
    date = datetime.datetime.today()
    week = date.strftime("%V")
    
    Entry.objects.filter(pub_date__week=week)


    from django.utils.timezone import now
    year, week, _ = now().isocalendar()
    
    Entry.objects.filter(pub_date__iso_year=year, pub_date__week=week)
    Ответ написан
  • Общий хостинг, клауд сервер или VPS - как выбрать свою "песочницу"?

    syschel
    @syschel
    freelance/python/django/backend
    Начать можно и с хостингов, со временем перейдя на виртуалки. Хватать сразу "всё и побольше", не стоит, да и не нужно в начале.
    Сложностей настройки с виртуалками нету. Как правило "продавец" вам предлагает выбор ОС, которые будут установлены с базовым набором софта. Не редко этого за глаза. Но если нет, то гайдов в интернете полно, а после хостинга уже будете примерно понимать что вам нужно установить и как.
    Ответ написан
    Комментировать
  • Как привязать тэг к посту в django?

    syschel
    @syschel
    freelance/python/django/backend
    В админке, если выбрать созданный тэг через shell, то в шаблоне он отображается как main.Tag.None. (main - название приложения) Как это исправить?

    Всё верно выводит.
    Post - это список постов, вы выводите только один. К посту у вас привязан список тегов (не ForeignKey), сталобыть вам список и выводят, который вы должны обработать.
    В шаблоне добавьте .all и увидете список тегов привязанных к даному посту.

    {{ post.tag.all }}

    Ну а дальше и обрабатывайте как список
    {% for tg in post.tag.all %}{{ tg.title }}{% endfor %}


    З.Ы. В модели поле с ManyToManyField лучше задавать имя переменной в множественном числе, то есть tags, а не tag.
    Ответ написан
    Комментировать
  • Как в Django прикрутить пользователя из кастомной системы регистрации?

    syschel
    @syschel
    freelance/python/django/backend
    Если нет возможности "переписать по человечески" и вы точно уверены что там "не по человечески", то три варианта:
    1. Писать свой context_processors и туда добавить всё что вы хотите получать от "классического" варианта. То есть дублировать классический функционал.
    2. Писать кастомную функцию, работающую с этой кастомной моделью пользователя. И везде где вам нужно, работать с этой функцией. То есть дублировать классический функционал.
    3. Геморно, но возможно. Переопределить AuthenticationMiddleware

    Кстати, по сути для п.1 нужна та же самая "функция". Просто способы вызова разные.
    Но лучше конечно же переписать по нормальному. Хотя и не всегда бизнесу это нужно (из-за 1-2 мелких правок, переписывать легаси код).
    Ответ написан
    3 комментария
  • Где ошибка в этом коде?

    syschel
    @syschel
    freelance/python/django/backend
    Смотрите на свой код:
    1. def page(request, key):
    2.     if key == 1:
    3.         a = 0
    4.         b = 50
    5.     data = table.objects.order_by("place")[a:b]

    1 строка, объявили функцию
    2 строк начали условие.
    3 и 4 строка, выполняется только если условие верное, то есть если key равен 1. Если приходит любое значение key кроме 1, то в вашем коде НЕ создаются переменные a и b.
    5 строка, вы пробуете использовать переменные которых не существует. Так как создаются они только при верном условии в строке 2.
    То есть, чтобы код работал, вам надо инициализировать переменные или до условия или после, хоть с нулевым значением. К примеру так:
    def page(request, key):
        a = 0
        b = 10
        if key == 1:
            a = 0
            b = 50
        data = table.objects.order_by("place")[a:b]

    или так
    def page(request, key):
        if key == 1:
            a = 0
            b = 50
        else:
            a = 0
            b = 10
        data = table.objects.order_by("place")[a:b]

    Программе не важно, что вы возможно планируете всегда передавать только 1, то есть у вас по планам условие будет выполнятся всегда, то есть в планах инициализация переменных произойдёт. Но вот программа этого не знает и она ругается.
    Ответ написан
    Комментировать