2013-12-13 4 views
0

Возможно ли получить объект request.user в функции, определенной для модели. Например:Получить объект request.user

class Event(models.Model): 
    description = models.TextField() 
    author = models.ForeignKey(User) 

    def has_upvoted(self): 
     return Up.objects.filter(user = self.request.user, 
          event = self.id) 

Я использую Джанго «пользователь» модель, которая позволяет «request.user» вернуть объект пользователя. Возможно ли получить его в вышеуказанной функции? has_upvoted() '. Кроме того, фильтр seconf, используемый в приведенной выше функции, принимает экземпляр самой модели «Событие». То, что я написал, неверно. Итак, каков правильный способ сделать это?

ответ

0

Да, но это не очень хорошо, пожалуйста, увидеть:

https://djangosnippets.org/snippets/2179/

Я не знаю другого пути

+0

Явное пропускание пользователя в качестве аргумента выглядит очень очевидным для меня ... Хак, к которому вы обращаетесь, действительно очень плохая практика по всем стандартам. –

+0

Да, это очень очевидно и легко ... Я ответил, потому что вопрос был другим, она обновила вопрос. – Goin

+0

cf Блог Джеймса Беннетта (http://www.b-list.org/weblog/2008/dec/24/admin/): «(...) то, что известно как« threadlocal hack », в основном это связано с приложением запроса .user в своего рода волшебную глобально доступную переменную, и это очень плохая вещь, которую вы можете использовать, если не знаете, что делаете. Это также, как правило, очень плохая вещь, даже если вы знаете, потому что вы, вероятно, просто делаете это, потому что вы ленивы и не хотите, чтобы вы правильно передавали информацию. Поэтому, если вы видите, что кто-то предлагает вам сделать это, используя «threadlocal», игнорируйте этого человека.« –

0

Модели могут быть использованы вне запроса HTTP/цикл реакции (управление команды и т. д.), поэтому вы не можете предположить, что есть глобально доступный объект request. Единственный чистый способ сделать «текущий request.user» доступным вам методам модели - явно передать его как аргумент. Это также сделает ваш код более надежным и надежным.

class Event(models.Model): 
    description = models.TextField() 
    author = models.ForeignKey(User) 

    # strange naming... looks like a predicate 
    # but acts as a getter ??? 

    def has_upvoted(self, user): 
     return Up.objects.filter(
      user=self.request.user, 
      event=self.id) 

Затем на ваш взгляд:

def whatever(request, ...): 
    event = get_your_event(...) 
    ups = event.has_upvoted(request.user) 

Если вам нужен прямой доступ из шаблонов, которые Вы должны будете обернуть вызов в пользовательский тег шаблона или фильтра, в зависимости от того, что has_upvoted действительно должен быть (предикат или сбруя)

версия templatetag:

# yourapp/templatags/whatever.py 
@register.assignement_tag 
def has_upvoted(event, user): 
    return event.has_upvoted(user) 

, а затем

# yourtemplates/whatever.html 

{% has_upvoted evt request.user as whatever %} 
{{ whatever }} 
более

о пользовательских тегов и фильтров здесь: https://docs.djangoproject.com/en/1.6/howto/custom-template-tags/

+0

Не могли бы вы проиллюстрировать, как это сделать? – toothie

+0

Прошу прощения? Вы говорите, что не знаете, как передать аргумент методу? –

+0

что угодно (request, request.user) ... – Jingo

1

Я думаю, вам просто нужно M2M поле для голосов. Что-то вроде этого:

class Event(models.Model): 
    description = models.TextField() 
    author = models.ForeignKey(User) 
    voted_users = models.ManyToManyField(User, related_name='voted_events') 

Затем вы можете использовать:

request.user.voted_events.all() 

или

if specified_event in request.user.voted_events: 
    print "%s up voted by %s" % (specified_event.description, request.user.username) 

Ваш метод has_upvoted() не является хорошей идеей.

+0

Эта модель не подходит для моих нужд. – toothie

Смежные вопросы