Ответы пользователя по тегу Django
  • Как настроить smtp почту в Django?

    @gh0sty Автор вопроса
    Веб-разработчик. Пишу под Python Django.
    Причина - закрытые исходящие порты. Но я даж постфикс поставил, думая, что моя ошибка)
    Ответ написан
    Комментировать
  • Можно ли сделать временную переменную для сессии Django?

    @gh0sty
    Веб-разработчик. Пишу под Python Django.
    Встроенного варианта нет, только для всей сессии.

    Решение:
    Просто закинь в request.session['weather_expires'] = (DateTime Object). Тип запиши когда он истекает (timezone.now() + timedelta(1) # 1 день), и лезь в middleware. Просто установи свой middleware класс, закинь дефолтный код из документации и если timezone.now > weather_expires - удаляй оба ключа.

    Не сцы, эт ez.
    Ответ написан
  • Как устранить ошибку "relation does not exist" в Django?

    @gh0sty Автор вопроса
    Веб-разработчик. Пишу под Python Django.
    Окей я разобрался.
    Краткий гайд по менеджменту большого количества полей, на примере библиотеки Django modeltranslation. Все происходит на сервере и на PostgreSQL. Причина: "tables can have at most 1600 columns" и "row is too big: size ..., maximum size 8160"
    1. Для начала создаем все наши поля на перевод у меня их около 400.
    2. Считаем количество нужных языков + 1, у меня это 6. Почему? Modeltranslation оставляет оригинальное поле, чтоб быстро к нему обращаться на уже смененном языке. Т.е. динамическая удобная фича)
    3. 400 * 6 = 2400 полей по итогу.
    4. Эти 2400 делим примерно на 600-800 (если charfield max_length=200). На моем примере - хватило 5.
    5. Разбиваем наш models и translation на 5 (вычислено выше) приложений. Это по 600 переводных строк, у меня, т.е. 100 обычных строк (+- 10).
    6. Создаем базы под эти приложения (ну это не нуждается в пояснении, create + grant).
    7. Создаем в settings ручные роуты, я их так называю. Пример:

      DATABASES = {
          'default': {  # Сюда будут записываться другие приложения, оставить "default"!!!
                  'ENGINE': 'django.db.backends.postgresql_psycopg2',
                  'NAME': 'db',
                  'USER': 'username',
                  'PASSWORD': 'pass',
                  'HOST': 'localhost',
                  'PORT': '',
          },
          't': {
                  'ENGINE': 'django.db.backends.postgresql_psycopg2',
                  'NAME': 'db_t',
                  'USER': 'username',
                  'PASSWORD': 'pass',
                  'HOST': 'localhost',
                  'PORT': '',
          },
          't2': {
                  'ENGINE': 'django.db.backends.postgresql_psycopg2',
                  'NAME': 'db_t2',
                  'USER': 'username',
                  'PASSWORD': 'pass',
                  'HOST': 'localhost',
                  'PORT': '',
          },
          't3': {
                  'ENGINE': 'django.db.backends.postgresql_psycopg2',
                  'NAME': 'db_t3',
                  'USER': 'username',
                  'PASSWORD': 'pass',
                  'HOST': 'localhost',
                  'PORT': '',
          },
          't4': {
                  'ENGINE': 'django.db.backends.postgresql_psycopg2',
                  'NAME': 'db_t4',
                  'USER': 'username',
                  'PASSWORD': 'pass',
                  'HOST': 'localhost',
                  'PORT': '',
          },
          't5': {
                  'ENGINE': 'django.db.backends.postgresql_psycopg2',
                  'NAME': 'db_t5',
                  'USER': 'username',
                  'PASSWORD': 'pass',
                  'HOST': 'localhost',
                  'PORT': '',
          }
      }


    8. Записываем их все в приложения. НО!!! закомментируем.
    9. В папках migrations в каждом приложении перевода удаляем все, кроме кеша и _init_.
    10. Проводим на всяк случай makemigrations и migrations без параметров для остальных приложений, чтобы удостовериться что все будет записано правильно.
    11. Далее раскомментируем в settings самое первое приложение. И применяем:

      manage.py makemigrations <название приложения перевода>
      manage.py migratе <название приложения перевода> --database=t<номер базы>
      manage.py migratе
      manage.py runserver <параметры>
      *Создаем тестовый экземпляр*
      manage.py update_translation_fields

      И проводим этот набор операций один за одним для каждого приложения.


    Это делается, чтобы не было бредовых ошибок. Уж поверьте их может быть море. Если что-то не получается пересоздаем базы данных (желательно с новым именем), чистим migrations и начинаем сначала. Если что-то явно не получается - гуглим ошибку. Тут основная часть всей дичи, которая может вам встретиться.
    Ответ написан
    Комментировать
  • Как создать thumbnail pillow image после сохранения в модели django?

    @gh0sty Автор вопроса
    Веб-разработчик. Пишу под Python Django.
    7 долбанных часов...
    Это было дико, мать твою!


    Подробности (не ручаюсь за инфу, мейби говнокодеры с форумов пишут вслепую):
    1. Значт так, в какой-то версии Django метод super save стал break-ать метод save модели
    2. В какой-то еще версии Django запретили создавать папки изменением self.image.name. Но разрешили в upload_to закидывать функцию с неявными (встроенными) аргументами без возможности добавления (!)
    3. Решил не париться save и post_save - просто создал внутренний метод и вызываю его перед super save.


    Це мой идеальный модельный код:
    def get_path_upload_image(instance, filename):
        """
        Переопределение имени и путя фотографии, сокращение названия
        В следующий формат: (media)/photos/username/2019-08-20/photo-name_23-59-59.extension
        """
        if '/' in filename:
            filename = filename.split('/')[-1]
        img_header, img_extension = os.path.splitext(filename)
        if len(img_header) > 30:
            if img_header[-6:] == '_thumb':
                img_header = img_header[:30] + '_thumb'
            else:
                img_header = img_header[:30]
        time = timezone.now().strftime('%Y-%m-%d')
        img_name = img_header + '_' + time + img_extension
        path = os.path.join('photos', '{}', '{}', '{}').format(instance.user.username, time, img_name)
        return path
    
    
    class Photo(models.Model):
        """ Фото """
        user = models.ForeignKey(User, verbose_name='Пользователь', on_delete=models.CASCADE)
        name = models.CharField('Имя', max_length=50)
        image = models.ImageField('Фото', upload_to=get_path_upload_image, blank=True, null=True)
        thumbnail = models.ImageField('Превью', upload_to=get_path_upload_image, editable=False, blank=True, null=True)
        order = models.PositiveSmallIntegerField('Порядковый номер', null=True, blank=True)
        is_main = models.BooleanField('Главное', default=False)
        created = models.DateTimeField('Дата создания', auto_now_add=True)
        slug = models.SlugField('url', max_length=50, unique=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = 'Изображение'
            verbose_name_plural = 'Изображения'
    
        def save(self, *args, **kwargs):
            self.make_thumbnail()
            super(Photo, self).save(*args, **kwargs)
    
        def make_thumbnail(self):
            image = Image.open(self.image)
            image.thumbnail((120, 80), Image.ANTIALIAS)  # ваш размер thumbnail
            thumb_name, thumb_extension = os.path.splitext(self.image.name)
            thumb_filename = thumb_name + '_thumb' + thumb_extension
            temp_thumb = BytesIO()
            image.save(temp_thumb, 'JPEG')
            temp_thumb.seek(0)
            self.thumbnail.save(thumb_filename, ContentFile(temp_thumb.read()), save=False)
            temp_thumb.close()


    Це мой views:
    ph = Photo(user=profile.user, order=request.POST.get('files_uploaded'))
    im = Image.open(photo_upload_form.cleaned_data['image'])
    im = im.convert('RGB')
    blob = BytesIO()
    if im.width > 1920 or im.height > 1080:
        output_size = (1920, 1080)
        im.thumbnail(output_size)
        im.save(blob, 'JPEG', quality=100)
    ph_name = 'gallery{}-{}.jpg'.format(gal.id, timezone.now().strftime('%Y-%m-%d-%H-%M-%S'))
    ph.name = ph_name
    ph.slug = slugify(ph_name)
    ph.image.save(ph_name, File(blob), save=False)
    ph.save()


    Если че - он сжимает полученное изображение до 1920x1080, закидывает его в photo и автоматически генерит thumbnail - да еще и генерируя путь в зависимости от даты и username.
    Ответ написан
    1 комментарий
  • Как исправить ошибку "Uncaught TypeError: Cannot read property 'style' of undefined" в jQuery DataTables?

    @gh0sty Автор вопроса
    Веб-разработчик. Пишу под Python Django.
    Нашел решение. Как оказалось нельзя использовать colspan, если у тебя нет, как минимум, 2х строк thead, т.е. colspan применим только к complex header.
    Фикс:
    ...
    <thead class="bg text-white font-weight-bold">
        <tr class="d-none">
            <th></th>
            <th></th>
            <th></th>
            <th class="d-none d-md-table-cell"></th>
            <th></th>
            <th></th>
        </tr>
        <tr>
            <th colspan="3">Объявление</th>
            <th class="d-none d-md-table-cell" data-toggle="tooltip" data-placement="top" title="Сортировать">Дата</th>
            <th data-toggle="tooltip" data-placement="top" title="Сортировать">Статус</th>
            <th data-toggle="tooltip" data-placement="top" title="Сортировать">Цена</th>
        </tr>
    </thead>
    ...

    и еще 1 параметр к инициализации DataTable:
    columnDefs: [
        { orderable: false, targets: [ 0, 1, 2 ] }
    ]


    Пасибки WhiteBearDev, хоть я и не въехал сразу.
    Ответ написан
    Комментировать
  • Django - как сохранить выбор одного значения из нескольких в переменную в шаблоне html и использовать ее в дальнейшем?

    @gh0sty
    Веб-разработчик. Пишу под Python Django.
    Во первых, сделай какую-нибудь валюту основной. Чтобы не парится с перерасчетами.
    Во вторых, передавай в темплейт (через контекст) свои коэффициенты + базовую валюту.
    В третьих, сделай изменения визуальными через JS.
    Например, по клику на валюту изменяй цены:
    var price = {{price}};
    var usd_to_eur = {{coeff.usd_to_eur}};
    var usd_to_btc = {{coeff.usd_to_btc}};
    $('#eur_btn').on('click', function () {
        var new_price = price * usd_to_eur;
        $('#price').text(new_price);
    });
    ...

    В четвертых, если это форма, до добавь hidden input с ценой в USD.

    Если хочешь проще - передавай в темплейте (в контексте) уже готовые цены и просто меняй по клику.

    Теперь о сессиях и выборе валюты.
    По клику на валюту (также) передавай ajax-запрос на выделенный урл и сохраняй в сессии

    Если что - будет выглядеть как-то так:
    $('#eur_btn').on('click', function () {
        $.ajax({
            url : "/valutes/eur/",
            type : "post",
            data : $('#hidden-input-form').serialize()
        });
    });
    ...

    Где #hidden-input-form форма, метода post, состоящая только из hidden input "valute". Крч, невидимая форма с твоими долларами и пр. Не забудь про csrf_token!
    Ответ написан
    Комментировать