2017-01-29 12 views
0

У меня есть модель профиля, выглядит следующим образом:Model.objects.get() работает, но не при использовании атрибута ForeignKey

class Profile(models.Model): 
    username = models.ForeignKey(User, blank=True, null=True) 
    age = models.IntegerField(default=0) 
    points = models.IntegerField(default=100) 

    def __str__(self): 
     return str(self.username) 

Вот мой шаблон

<h3><a href="{% url 'profile' u=i.user %}" class='username_foreign'>{{ i.user }}</a></h3> 

, которая указывает на это URL:

url(r'^profile/(?P<u>\w+)/', profile, name='profile') 

и вот моя точка зрения функции:

def profile(request, u): 
    if request.method == 'GET': 
     profile = Profile.objects.get(username=u) 

    return render(request, 'base.html', {}) 

Как вы можете видеть здесь, я прохожу через u, который является именем пользователя. Но когда я пытаюсь get()profile через username прошел через, я получаю эту ошибку:

ValueError at /profile/zorgan/ 

invalid literal for int() with base 10: 'zorgan' 

Однако, когда я использую get() на любой другой атрибут моей Profile модели, она прекрасно работает. И он даже печатает мой username. Так что, когда я делаю это:

def profile(request, u): 
    if request.method == 'GET': 
     print(u) #prints username 
     profile = Profile.objects.get(points=50) 
     print(profile.username) #successfully prints username (same as 'u') 

    return render(request, 'base.html', {}) 

Как вы можете видеть выше, получая Profile объект через его атрибут не работает username. И проблема не связана с u, так как это успешно печатает. Любая идея, в чем проблема?

ответ

4

Поле, которое вы назвали username, не является именем пользователя. Это ForeignKey, который представляет собой целочисленное значение, указывающее на строку в другой таблице. Вы должны назвать это, что это такое: user.

Чтобы найти фактическое имя пользователя в таблице User, вам нужно использовать синтаксис с двойным подчеркиванием. Это будет работать:

profile = Profile.objects.get(username__username=u) 

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

profile = Profile.objects.get(user__username=u) 

Другим способом сделать это было бы посмотреть на пользователе напрямую, а затем получить профиль:

, но это требует двух отдельных запросов, а не одного из них.

+0

Спасибо, что решает проблему. Я не слишком хорошо знаком с синтаксисом double __, так что вы можете дать краткое резюме или указать мне где-нибудь, что объясняет это? Почему он используется для полей ForeignKey, а не для других? – Zorgan

+1

Поскольку значение имени пользователя равно * в другой модели *, т.е. User. –