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

    Нужно указать MEDIA_URL.
    У поля, в котором хранится запись о файле нужно вывести в шаблон значение атрибута url (Пример).
    Для загрузки нескольких файлов к одному материалу надо использовать formsets.
    Ответ написан
    Комментировать
  • Как аккуратно переместить некоторые записи из одной БД в другую в Django?

    Надо немного подправить модели точнее моделям добавить менеджеры. Добавить правило сериализации связей get_by_natural_key() https://docs.djangoproject.com/en/2.0/topics/seria.... Потом dumpdata на тестовом и loaddata на проде.
    Для подобных танцев лучше отдельную ветку сделать, чтобы перенести данные, а потом её удалить и забыть как страшный сон.
    Ответ написан
    Комментировать
  • Как вытащить данные по URI (DRF)?

    Думаю, что подобное имелось ввиду
    from urllib import parse
    from django.urls import resolve
    
    uri = '/api/v1/myapp?my_filter=my_value'
    data = parse.urlsplit(uri)
    path = data.path
    params = dict(parse.parse_qsl(data.query))
    viewset = resolve(data.path).func.cls
    queryset = viewset.filter_class(data=params).qs
    Ответ написан
    Комментировать
  • Как правильно отпарсить JSON во view Django?

    NogerbekNurzhan, можно попробовать так
    class DocumentOrderView(CsrfExemptMixin, JsonRequestResponseMixin, FormView):
        def post(self, request, *args, **kwargs):
            self.tree_update(None, self.request_json)
            return self.render_json_response({'saved': 'ok'})
    
        @staticmethod
        def tree_update(parent_id, children):
            for child in children:
                Tree.objects.filter(pk=child['id']).update(parent_id=parent_id)
                tree_update(child['id'], child.get('children', []))
    Ответ написан
    7 комментариев
  • Как объединить приложения django-modeltranslation и django-reversion?

    в @reversion.register() можно параметр fields передать, это те поля за которыми reversion будет следить
    @reversion.register(fields=['head', 'head_en', 'head_kz',])
    class Slide(models.Model):
        head = models.CharField(verbose_name='Title', max_length=200, blank=False,)
    Ответ написан
    2 комментария
  • Как правильно сделать переадресацию пользователя, если у него нет права доступа к вью?

    Можно переопределить немного и получить, что-то такое.
    from django.shortcuts import redirect
    
    
    class RedirectPermissionRequiredMixin(PermissionRequiredMixin,):
        login_url = reverse_lazy('dashboard')
    
        def handle_no_permission(self):
            return redirect(self.get_login_url())
    
    # и примешать вместо PermissionRequiredMixin
    class UserEditView(RedirectPermissionRequiredMixin, UpdateView):
        template_name = 'users/edit_user.html'
        form_class = UserEditForm
        model = User
        permission_required = ('auth.change_user')
    Ответ написан
    9 комментариев
  • Как правильно написать serializer?

    class ModelBSerializater(serializers.ModelSerializer):
        name_a = serializers.ReadOnlyField(source='modela.name')
        class Meta:
            model = ModelB
            fields = (..., name_a)
    Ответ написан
  • Как сделать регистрацию через активацию django?

    Я для активации аккаунта использовал механизм восстановления пароля. Получилось, примерно, так.
    views.py
    ...
            user.is_active = False
            user.save()
            context = {'user': user}
    
            current_site = get_current_site(request)
            site_name = current_site.name
            domain = current_site.domain
    
            use_https = request.is_secure()
            token_generator = user_is_active_token_generator
            extra_context = {
                'domain': domain,
                'site_name': site_name,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'user': user,
                'token': token_generator.make_token(user),
                'protocol': 'https' if use_https else 'http',
            }
            context.update(extra_context)
            mail_message_template = 'путь до registration_email_user_not_is_active.html'
            mail_message = render_to_string(mail_message_template, context)
    
            send_mail('activation JustSolve.kz', mail_message, settings.EMAIL_HOST_USER, ['knursultana@gmail.com'])

    tokens.py (он почти такой же как и django.contrib.auth.tokens)
    from django.conf import settings
    from django.contrib.auth.tokens import PasswordResetTokenGenerator
    from django.utils import six
    from django.utils.crypto import constant_time_compare, salted_hmac
    from django.utils.http import base36_to_int, int_to_base36
    
    
    class UserIsActiveTokenGenerator(PasswordResetTokenGenerator):
    
        def check_token(self, user, token):
            """
            Check that a password reset token is correct for a given user.
            """
            # Parse the token
            try:
                ts_b36, hash = token.split("-")
            except ValueError:
                return False
    
            try:
                ts = base36_to_int(ts_b36)
            except ValueError:
                return False
    
            # Check that the timestamp/uid has not been tampered with
            if not constant_time_compare(self._make_token_with_timestamp(user, ts), token):
                return False
    
            return True
    
        def _make_token_with_timestamp(self, user, timestamp):
            # timestamp is number of days since 2001-1-1.  Converted to
            # base 36, this gives us a 3 digit string until about 2121
            ts_b36 = int_to_base36(timestamp)
    
            # By hashing on the internal state of the user and using state
            # that is sure to change (the password salt will change as soon as
            # the password is set, at least for current Django auth, and
            # last_login will also change), we produce a hash that will be
            # invalid as soon as it is used.
            # We limit the hash to 20 chars to keep URL short
            key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
    
            # Ensure results are consistent across DB backends
            joined_timestamp = '' if user.date_joined is None else user.date_joined.replace(microsecond=0, tzinfo=None)
    
            value = (six.text_type(user.pk) +
                     six.text_type(joined_timestamp) + six.text_type(timestamp))
            hash = salted_hmac(key_salt, value).hexdigest()[::2]
            return "%s-%s" % (ts_b36, hash)
    
    user_is_active_token_generator = UserIsActiveTokenGenerator()

    registration_email_user_not_is_active.html
    Dear, {{ user.username }}!<br>
    You join to {{ domain }}!<br>
    
    url to activate <a href="{{ protocol }}://{{ domain }}/activate/{{ uid }}/{{ token }}/">{{ protocol }}://{{ domain }}/activate/{{ uid }}/{{ token }}/</a>
    
    welcome!

    urls.py
    ...
        url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
            views.activate, name='activate')
    ...

    views.py
    def activate(request, uidb64=None, token=None,
                 token_generator=user_is_active_token_generator,
                 template_name='common/activate.html'):
    
        UserModel = get_user_model()
        assert uidb64 is not None and token is not None  # checked by URLconf
    
        try:
            # urlsafe_base64_decode() decodes to bytestring on Python 3
            uid = force_text(urlsafe_base64_decode(uidb64))
            user = UserModel._default_manager.get(pk=uid)
        except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
            user = None
    
        if user is not None and user.is_active:
            validlink = True
            title = _('Link no longer relevant')
        elif user is not None and token_generator.check_token(user, token):
            user.is_active = True
            user.save()
    
            validlink = True
            title = _('Account activated')
        else:
            validlink = False
            title = _('Link not correct')
        context = {
            'title': title,
            'validlink': validlink,
        }
    
        return TemplateResponse(request, template_name, context)

    При таком подходе не понадобится дополнительная модель Activation или какие-то поля в бд.

    # Проверки должны находиться в django forms, а не во вьюхе.
    validate_email(email)
    len(password) >= 5
    password != password2
    User.objects.filter(username=email, is_active=True).exists()
    Ответ написан
    Комментировать
  • Как мне проверить этих чекбоксов?

    Что-то какая-то мешанина.
    в одном месте возвращается list из request.POST.getlist('checks[]'), а в другом месте проверяется на число request.POST['checks[]'].isdigit()
    Ответ написан
  • Два сайта на одной базе данных на Django?

    Создать файлы manage2.py settings2.py urls2.py. В manage2.py прописать settings2, а в settings2.py прописать urls2.
    Первый сайт будет запускаться ./manage.py runserver
    Второй будет запускаться ./manage2.py runserver
    Ответ написан
  • Как спрятать админку Django?

    Можно закрыть адрес через basic authentication https://www.digitalocean.com/community/tutorials/h...

    Можно админку вынести на другой домен. Для этого нужно будет создать 3 дополнительныйх файла:
    • manage2.py (такой же как и manage.py, только в строке os.environ.setdefault("DJANGO_SETTINGS_MODULE", "название_приложения.settings") settings изменить на settings2)
    • settings2.py (такой же как и settings.py, только в строке ROOT_URLCONF = 'название_приложения.urls2' заменить urls на urls2)
    • urls2.py (тут оставить только урл админки)

    Соответственно, после того как админка уберется на другой домен на основном домене доступ к админке убрать из urls.py
    Ответ написан
    Комментировать
  • Получаю дублирующие записи при обновлении страницы через ajax?

    Тут происходит такая ситуация, к примеру после загрузки страницы есть 2 коммента.
    После чего ajax возвращает, как я понимаю, те же 2 коммента или больше(возьмем случай с 2-мя). Дальше происходит $('.comment').html(data);. Вот тут находятся 2 блока с классом ".comment" и в каждый вставляются те данные которые пришли от сервера, соответственно в первый блок добавится 2 записи и во второй блок 2 записи. Вот тут и дублирование.
    Не знаю, что отдает сервер, по-этому сделаю предположу:
    - сервер отдает
    <div class="comment">
        <p id="inf"> {{ comment.name }} {{ comment.created }}</p>
        {{ comment.body|linebreaks }}
    </div>

    тогда надо заменить $('.comment').html(data); на
    $('.comment').remove();
    $('#codeajax').append(data);


    И еще.
    Косяк с версткой, возможно в нем основная проблема, так как в цикле закрывается div#codeajax.
    Ответ написан
    Комментировать
  • Как выделить активный пункт меню?

    думаю, что это не хорошо хардкодить урлы, ведь есть же {% url %}
    И тогда подобных недоразумений не будет.
    {% url 'phylosophy' as url %}
    <a href='{{ url }}' {% if request.path == url %}class="active"{%endif %}>philosophy</a>
    Ответ написан
  • Как сделать хлебные крошки как в админке?

    можно сделать так. В base.html прописать блок для хлебных крошек.
    {% block breadcrumbs %}
        <div class="breadcrumb"><a href="/">Главная</a></div>
    {% endblock %}

    К примеру есть Каталог Статей и отдельный просмотр Статьи. И шаблоны для них articles.html и article.html
    articles.html
    {% extends 'base.html' %}
    
    {% block breadcrumbs %}
        {{ block.super }}
        <div class="breadcrumb"><a href="{% url 'articles:articles' %}">Каталог статей</a></div>
    {% endblock %}


    article.html
    {% extends 'articles.html' %}
    
    {% block breadcrumbs %}
        {{ block.super }}
        <div class="breadcrumb"><a href="{% url 'articles:article_view' article_id=article.id %}">{{ article.title }}</a></div>
    {% endblock %}
    Ответ написан
    Комментировать
  • NoReverseMatch?

    Для начала, надо внимательнее читать. Тут есть описание polls/urls.py, сравните со своими урлами.
    Ответ написан
    5 комментариев
  • Как загрузить изображение с формы в django?

    Название класса class User_profile в pep8 написано следущее:
    Class names should normally use the CapWords convention.

    По поводу ошибки с urllib ответил Alexander .
    Вторая проблема заключается в магии которая происходит в коде.
    Форму SignupForm лучше не делать полностью ручками, а унаследовать от
    from django.contrib.auth.forms import UserCreationForm

    Так же эту форму лучше разбирь на две, соответственно первая относится к User, а вторая к UserProfile(или User_profile, но так не по pep8)
    Сохранение аватарки оставить на Джангу, для этого надо немного поправить модель
    import os
    from django.contrib.auth.models import User
    
    from django.db import models
    
    
    def avatar_upload_to(instance, filename):
        return os.path.join('uploads', instance.user.username + os.path.splitext(filename)[1])
    
    
    class UserProfile(models.Model):
        user = models.OneToOneField(User, unique=True)
        avatar = models.ImageField(upload_to=avatar_upload_to)
        info = models.TextField()

    Далее сделать привожу две формы, которые получились после разделения SignupForm
    from django import forms
    from django.contrib.auth.forms import UserCreationForm
    from django.contrib.auth.models import User
    from accounts.models import UserProfile
    
    
    class SignupForm(UserCreationForm):
    
        username = forms.CharField(
            widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'login', }),
            max_length=30, label=u'Логин'
        )
        email = forms.EmailField(
            widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Ваша почта', }),
            required=True, max_length=254, label=u'E-mail',
        )
        password1 = forms.CharField(
            widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '*****'}),
            min_length=6, label=u'Пароль'
        )
        password2 = forms.CharField(
            widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '*****'}),
            min_length=6, label=u'Повторите пароль'
        )
    
        class Meta:
            model = User
            fields = ('username', 'email')
    
    
    class UserProfileSignupForm(forms.ModelForm):
    
        info = forms.CharField(
            widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': u'Молод и горяч',}),
            required=False, label=u'Пара слов о себе'
        )
        avatar = forms.FileField(
            widget=forms.ClearableFileInput(attrs={'class': 'ask-signup-avatar-input',}),
            required=False, label=u'Аватар'
        )
    
        def clean_avatar(self):
            avatar = self.cleaned_data.get('avatar')
            if avatar is None:
                raise forms.ValidationError(u'Добавьте картинку')
            if 'image' not in avatar.content_type:
                raise forms.ValidationError(u'Неверный формат картинки')
            return avatar
    
        class Meta:
            model = UserProfile
            fields = ('info', 'avatar')

    в settings.py надо добавить пути ко всем медиа файлам
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
    
    MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media')
    MEDIA_URL = '/media/'

    Мда, все сюда выкатывать не хочется.
    Сделал репозиторий, можно посмотреть тут
    Ответ написан
  • Как сохранить из формы в модель несколько картинок?

    В одну модель сохранить несколько кортинок нельзя(если поле для картинок одно).
    Для сохранения картинок нужно создать новую модель.
    models.py
    class Advert(models.Model):
        category = models.TextField()
        title = models.CharField(max_length=64)
        description = models.CharField(max_length=900)
        date = models.DateTimeField(auto_now_add=True, null=True)
    
    
    class AdvertImage(models.Model):
        advert = models.ForeignKey(Advert)
        photo = models.ImageField(upload_to='uploads/')

    forms.py
    class AddAdvertForm(ModelForm):
        class Meta:
            model = Advert
            fields = '__all__'
    
    
    class AdvertImagesForm(forms.Form):
    
        photos = forms.FileField(widget=widgets.FileInput(attrs={'multiple': True}))
    
        def __init__(self, *args, **kwargs):
            if 'request' in kwargs:
                self.request = kwargs.pop('request')
            super(AdvertImagesForm, self).__init__(*args, **kwargs)
    
        def clean_photos(self):
            # Остаются только картинки
            photos = [photo for photo in self.request.FILES.getlist('photos') if 'image' in photo.content_type]
            # Если среди загруженных файлов картинок нет, то исключение
            if len(photos) == 0:
                raise forms.ValidationError(u'Not found uploaded photos.')
            return photos
    
        def save_for(self, advert):
            for photo in self.cleaned_data['photos']:
                AdvertImage(photo=photo, advert=advert).save()

    views.py
    class CreateAdvertView(View):
        template_name = 'bulletinboard/add_advert.html'
        form_class = AddAdvertForm
        form_images_class = AdvertImagesForm
        model = Advert
    
        def get(self, request):
            form = self.form_class()
            form_images = self.form_images_class()
            return render(request, self.template_name, {'form': form, 'form_images': form_images})
    
        def post(self, request):
            form = self.form_class(request.POST)
            form_images = self.form_images_class(request.POST, request.FILES, request=request)
            if form.is_valid() and form_images.is_valid():
                advert = form.save()
                form_images.save_for(advert)
                return HttpResponseRedirect('/')
            return render(request, self.template_name, {'form': form, 'form_images': form_images})
    Ответ написан
    7 комментариев
  • Как загрузить файл в django с кириллическим названием?

    возможно это не самый разумный способ, но для быстрого решения подойдет.
    Смысл в переписывании родных-джанговских upload handlor'ов
    в settings.py
    FILE_UPLOAD_HANDLERS = (
        'название_аппликейшена.uploadhandler.MemoryFileUploadHandler',
        'название_аппликейшена.uploadhandler.TemporaryFileUploadHandler',
    )

    И соответственно uploadhandler.py
    from io import BytesIO
    import os
    from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile
    from django.core.files.uploadhandler import FileUploadHandler, StopFutureHandlers
    from django.conf import settings
    import pytils
    import re
    
    
    def translify(value):
        value = pytils.translit.translify(u"%s" % value)
        value = re.sub("[\W]", "_", value.strip())
        return value
    
    
    def transliteration_file_name(file_name):
        name, ext = os.path.splitext(file_name)
        return '{0}{1}'.format(translify(name), ext)
    
    
    class TemporaryFileUploadHandler(FileUploadHandler):
        """
        Upload handler that streams data into a temporary file.
        """
    
        def __init__(self, *args, **kwargs):
            super(TemporaryFileUploadHandler, self).__init__(*args, **kwargs)
    
        def new_file(self, field_name, file_name, content_type, content_length, charset=None, content_type_extra=None):
            file_name = transliteration_file_name(file_name)
            super(TemporaryFileUploadHandler, self).new_file(field_name, file_name, content_type,
                                                             content_length, charset, content_type_extra)
            self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra)
    
        def receive_data_chunk(self, raw_data, start):
            self.file.write(raw_data)
    
        def file_complete(self, file_size):
            self.file.seek(0)
            self.file.size = file_size
            return self.file
    
    
    class MemoryFileUploadHandler(FileUploadHandler):
        """
        File upload handler to stream uploads into memory (used for small files).
        """
    
        def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
            """
            Use the content_length to signal whether or not this handler should be in use.
            """
            # Check the content-length header to see if we should
            # If the post is too large, we cannot use the Memory handler.
            if content_length > settings.FILE_UPLOAD_MAX_MEMORY_SIZE:
                self.activated = False
            else:
                self.activated = True
    
        def new_file(self, field_name, file_name, content_type, content_length, charset=None, content_type_extra=None):
            file_name = transliteration_file_name(file_name)
            super(MemoryFileUploadHandler, self).new_file(field_name, file_name, content_type,
                                                          content_length, charset, content_type_extra)
            if self.activated:
                self.file = BytesIO()
                raise StopFutureHandlers()
    
        def receive_data_chunk(self, raw_data, start):
            """
            Add the data to the BytesIO file.
            """
            if self.activated:
                self.file.write(raw_data)
            else:
                return raw_data
    
        def file_complete(self, file_size):
            """
            Return a file object if we're activated.
            """
            if not self.activated:
                return
    
            self.file.seek(0)
            return InMemoryUploadedFile(
                file=self.file,
                field_name=self.field_name,
                name=self.file_name,
                content_type=self.content_type,
                size=file_size,
                charset=self.charset,
                content_type_extra=self.content_type_extra
            )
    Ответ написан
    Комментировать