2012-07-26 10 views
5

Widziałem inną odpowiedź here i inne miejsca w sieci, które zalecają używanie user.get_profile podczas rozszerzania wbudowanego użytkownika django. Nie zrobiłem tego w poniższym przykładzie. Wydaje się, że funkcjonalność działa dobrze, ale czy jest jakiś minus, jeśli nie używasz user.get_profile()?Kiedy należy używać user.get_profile w django?

modelu

class UserProfile(models.Model): 
    user = models.ForeignKey(User, primary_key=True) 
    quote = models.CharField('Favorite quote', max_length = 200, null=True, blank=True) 
    website = models.URLField('Personal website/blog', null=True, blank=True) 

class UserProfileForm(ModelForm): 
    class Meta: 
     model = UserProfile 
     fields = ('quote', 'website') 

widok

@login_required 
def user_profile(request): 
    user = User.objects.get(pk=request.user.id) 
    if request.method == 'POST': 
     upform = UserProfileForm(request.POST) 
     if upform.is_valid(): 
      up = upform.save(commit=False) 
      up.user = request.user 
      up.save() 
      return HttpResponseRedirect('/accounts/profile') 
    else: 
     upform = UserProfileForm() 
    return render_to_response('reserve/templates/edit_profile.html', locals(), context_instance=RequestContext(request)) 
+0

Można upuścić wiersz 'user = User.objects.get (pk = request.user.id) w widoku. 'request.user' jest już instancją modelu użytkownika. Ponadto, 'locals()' jest podejrzanie nazwane; nie jest zdefiniowany w widoku, więc czy jest naprawdę lokalny? – JCotton

+2

@JCotton Używanie ['locals()'] (http://docs.python.org/library/functions.html#locals) jest wbudowaną funkcją. Tutaj jest używany jako hack, aby uniknąć konieczności ręcznego definiowania słownika kontekstowego szablonu. To oszczędność czasu, ale prawdopodobnie lepiej jest określić kontekst. Dobry punkt na temat 'request.user'. – Alasdair

+0

@Alasdair hej, dzięki! nie wiesz, że o 'locals()' – JCotton

Odpowiedz

3

Kod działa jak napisałeś, ale dlatego, że nie przechodzą instancję do modelu to trochę nietypowa, więc to może poproś innego programistę Django o trochę dłużej, aby dowiedzieć się, co się dzieje.

Widok, który można utworzyć, aby utworzyć instancję modelu z instancją, aby istniejące wartości profilu były wyświetlane w formularzu. W twoim przypadku dostaniesz puste pola.

upform = UserProfileForm(instance=user.get_profile()) 

Ponieważ nie przewidują wystąpienie, oszczędzając spróbuje utworzyć nowy user_profile, których nie chcemy. Tak się nie stanie w twoim przypadku, ponieważ klucz podstawowy został user, ale to też trochę niezwykłe.

Główną zaletą pisania user.get_profile() jest to, że nie trzeba wiedzieć, który model jest używany dla profilu użytkownika. Jeśli jesteś zadowolony z kodu twardego UserProfile w swoim kodzie, możesz zamiast tego wstawić instance=UserProfile.objects.get(user=user).

+0

masz na myśli zastąpić wiersz "user = User.objects.get (pk = request.user.id)" z tym, co napisałeś powyżej, oprócz wymiany "upform = UserProfileForm (request.POST) "z" upform = UserProfileForm (instance = user.get_profile()) "? – sharataka

+0

Pozostaw linię użytkownika taką jaka jest, lub zastąp ją przez 'user = request.user' zgodnie z sugestią JCotton w powyższym komentarzu. Podczas tworzenia formularza, 'instancja' jest dodatkowym argumentem, nie zastępuje' data = request.POST'. Ustaw "instancję' * obie * razy podczas tworzenia formularza. – Alasdair