2015-10-23 7 views
0

У меня есть две модели, которые идут что-то вроде:Джанго: два внешних ключей для пользователей в модели, получить тот, который не пользователь, который загрузил страницу

class UserProfile(models.Model): 
    account = models.ForeignKey(MyUser, related_name='profiles') # MyUser is my custom user model 
    display_name = models.CharField(max_length=30) 
    ... 
    def get_all_contracts(self): 
     #returns all contracts associated with the profile 

class Contract(models.Model): 
    ... 
    employee = models.ForeignKey(UserProfile, related_name='employee_contracts') 
    employer = models.ForeignKey(UserProfile, related_name='employer_contracts') 
    ... 

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

{% for contract in user_profile.get_all_contracts %} 
    <h2>The other user is {{ contract.other_user.display_name }}</h2> 
{% endfor %} 

В этом примере other_user был бы мной ThOD.

Есть ли способ сделать это? Я не могу понять, как определить из метода, какой профиль является тем, который загружал страницу.

любая помощь оценена :)

+0

Это может быть проще реализовать как логику просмотра, так и фильтр шаблонов, поскольку самый простой способ получить запрос пользователя - 'request.user'. Таким образом, ваш 'other_user' будет пользователем двух, идентификатор которых не соответствует' request.user.id'. –

+0

@ Two-BitAlchemist Как бы реализовать его ias view logic, если я хочу использовать его в цикле for и не знаю, сколько контрактов get_all_contracts вернется? Каждый контракт будет с другим человеком, поэтому я не знаю, как передать его в контексте – dietbacon

ответ

1

Вы можете сделать это как тег шаблона. Что-то вроде:

from django import template 

register = template.Library() 

@register.simple_tag 
def get_other_user_display_name(user, contract): 
    try: 
     return [obj for obj in [contract.employee, contract.employer] \ 
       if obj != user][0].display_name 

     # if you don't like list comprehensions, you could do: 
     # set([contract.employee, contract.employer]) - set([user]) 
     # but I find this syntax to be less than obvious 
    except IndexError: 
     return '' 

Затем в цикле шаблона:

{% for contract in user_profile.get_all_contracts %} 
    <h2>The other user is {% get_other_user_display_name request.user contract %}</h2> 
{% endfor %} 

Если вы 100% уверены, что contract.employee и contract.employer отношений не будут аннулированы, вы можете устранить этот обработчик IndexError исключения.

В качестве альтернативы, вы можете сделать это в качестве тега присваивания, если вам необходимо получить доступ на другие свойства other_user:

@register.assignment_tag(takes_context=True) 
def get_other_user(context, contact): 
    # you can get request.user from the context 

    user = context['request'].user 

    return [obj for obj in [contract.employee, contract.employer] if obj != user][0] 

Затем в цикле вы можете получить доступ к любой свойства вы хотите.

{% for contract in user_profile.get_all_contracts %} 
    {% get_other_user contract as other_user %} 
    <h2>The other user is {{ other_user.display_name }}</h2> 
    <p>Their email is: {{ other_user.email }}</p> 
{% endfor %} 
+0

, есть ли способ сделать тег для любого свойства? Я не показывал в примере, но я хочу показать больше, чем просто отображаемое имя в каждом цикле. что-то вроде '{% get_other_user request.user contract property_name%}'? – dietbacon

+0

Несомненно. Я добавлю пример того, как вы можете сделать тэг назначения. – Brandon

+0

спасибо, Брэндон! Я прочитал документы о тегах присваивания. Хорошая идея. Я собираюсь использовать один из них. – dietbacon