как я получаю объекты запроса в django-сигналах [duplicate]

Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
21
задан Anto 30 July 2014 в 16:34
поделиться

9 ответов

Не может быть сделано. Текущий пользователь доступен только через запрос, который недоступен при использовании чисто функциональных возможностей модели. Получите доступ к пользователю в представлении.

11
ответ дан Ignacio Vazquez-Abrams 27 August 2018 в 02:36
поделиться

Вы также можете использовать django-reversion для этой цели, например.

from reversion.signals import post_revision_commit
import reversion

@receiver(post_save)
def post_revision_commit(sender, **kwargs):
    if reversion.is_active():
        print(reversion.get_user())

Подробнее об их API https://django-reversion.readthedocs.io/en/stable/api.html#revision-api

3
ответ дан bjorn 27 August 2018 в 02:36
поделиться

Игнасио прав. Модельные сигналы Django предназначены для уведомления других системных компонентов о событиях, связанных с экземплярами, и их уважаемых данных, поэтому, я думаю, это правда, что вы не можете, скажем, получить доступ к данным запроса из сигнала модели post_save, если только эти данные запроса не были сохранены или связанный с экземпляром.

Я предполагаю, что есть много способов справиться с этим, начиная от худшего до лучшего, но я бы сказал, что это пример prime для создания класса- основанные / основанные на функции общие представления, которые автоматически будут обрабатывать это для вас.

Пусть ваши представления, которые наследуют от CreateView, UpdateView или DeleteView, дополнительно наследуют от вашего класса AuditMixin, если они обрабатывают глаголов, которые работают с моделями, которые должны быть проверены. Затем AuditMixin может подключаться к представлениям, которые успешно создают \ обновлять \ удалять объекты и создавать запись в базе данных.

Делает совершенный смысл, очень чист, легко подключается и рождает счастливых пони. Оборотная сторона? Вы либо должны быть в выпуске выпущенной версии Django 1.3, либо вам придется потратить некоторое время, отвлекая на основе общих функций на основе функций и предоставляя новые для каждой операции аудита.

5
ответ дан Filip Dupanović 27 August 2018 в 02:36
поделиться

Почему бы не добавить промежуточное ПО с чем-то вроде этого:

class RequestMiddleware(object):

    thread_local = threading.local()

    def process_request(self, request):
        RequestMiddleware.thread_local.current_user = request.user

и позже в вашем коде (особенно в сигнале в этом разделе):

thread_local = RequestMiddleware.thread_local
if hasattr(thread_local, 'current_user'):
    user = thread_local.current_user
else:
    user = None
3
ответ дан firebird631 27 August 2018 в 02:36
поделиться

Я предполагаю, что вы поняли бы это, но у меня была та же проблема, и я понял, что все экземпляры, которые я создаю, имеют ссылку на пользователя, который их создает (это то, что вы ищете)

0
ответ дан kiril 27 August 2018 в 02:36
поделиться

Для отслеживания добавьте два атрибута к вашей модели (created_by и updated_by), в «updated_by» сохраните последнего пользователя, который изменил запись. Затем в вашем сигнале у вас есть пользователь:

models.py:

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    created_by = models. (max_length=100)
    updated_by = models. (max_length=100)

views.py

    p = Question.objects.get(pk=1)
    p.question_text = 'some new text'
    p.updated_by = request.user
    p.save()

signals.py

@receiver(pre_save, sender=Question)
def do_something(sender, instance, **kwargs):
    try:
        obj = Question.objects.get(pk=instance.pk)
    except sender.DoesNotExist:
        pass
    else:
        if not obj.user == instance.user: # Field has changed
            # do something
            print('change: user, old=%s new=%s' % (obj.user, instance.user))
4
ответ дан Nez 27 August 2018 в 02:36
поделиться

Посмотрите django-contrib-requestprovider , возможно, вы можете его использовать.

7
ответ дан om-nom-nom 27 August 2018 в 02:36
поделиться

Я смог сделать это, проверив стек и посмотрев представление, а затем посмотрел на локальные переменные для представления, чтобы получить запрос. Это похоже на хак, но это сработало.

import inspect, os

@receiver(post_save, sender=MyModel)
def get_user_in_signal(sender, **kwargs):
    for entry in reversed(inspect.stack()):
        if os.path.dirname(__file__) + '/views.py' == entry[1]:
            try:
                user = entry[0].f_locals['request'].user
            except:
                user = None
            break
    if user:
        # do stuff with the user variable
6
ответ дан PaulR 27 August 2018 в 02:36
поделиться
context_processors.py

from django.core.cache import cache

def global_variables(request):
    cache.set('user', request.user)

----------------------------------
in you model

from django.db.models.signals import pre_delete
from django.dispatch import receiver
from django.core.cache import cache
from news.models import News

@receiver(pre_delete, sender=News)
def news_delete(sender, instance, **kwargs):
    user = cache.get('user')

in settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    'web.context_processors.global_variables',
)
2
ответ дан Николай Сибилёв 27 August 2018 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: