0

For the past 2hrs i've been trying to accomplish the following in Django 1.5: I want to retrieve records from my database based on the user's email, which is stored in a session. Here are my ideal algorithms:

In my function based view:
1. Attempt Login
2. If account exists, log user in and save email in request.session['email']

In my DetailView:
1.Get the email from the session and save it to a variable; email.
2. Create a queryset to retrieve the account filtering by email

I've referenced the docs and a post on this matter but can't seem to get my head around it. I decided to use the get method to retrieve the session and it works...the only issue is i'm not sure how i can access the variable returned by this method. I looked at this answer but didn't find it too helpful. If this question exist else where point me to it so i can delete this one. Thanks!



#views.py CBV snippet
class AccountDetailView(DetailView):
    model = Account
    template_name = 'accounts/view_account.html'
    queryset = Account.objects.filter(verified=1)
    slug_field = 'username'
    slug_url_kwarg = 'username'

    def get(self, request, *args, **kwargs):
        email = request.session['email']
        #just to make sure we've accessed the session...print to screen
        return HttpResponse(email)

#views.py FBV snippet
def AccountLogin(request):
    template_name = 'accounts/login.html'
    if request.method == 'POST':
        form = AccountLoginForm(request.POST)
        if form.is_valid() and form is not None:
            clean = form.cleaned_data
            try:
                #only allow login for verified accounts
                account = Account.objects.get(email=clean['email'])
                if account and account is not None and account.verified == 1:
                    #if account exist log user in
                    user = authenticate(username=clean['email'], password=clean['password'])
                    #we'll user this later to pull their account info
                    request.session['email'] = account.email
                    #logs user in
                    login(request, user)


This is the solution in a function based view...how do i implement it in class based view is what i'm asking.


def AccountView(request): 
    account = Account.objects.get(verified=1, email=request.session['email'])
    return render(request, 'accounts/view_account.html', {'account': account})

Community
  • 1
  • 1
Staccato
  • 614
  • 1
  • 7
  • 17
  • I'll leave this up here in case someone else has a similar question...I'm done with CBVs i'll just stick to FBVs. – Staccato Aug 06 '13 at 03:36

2 Answers2

0

You are doing it seriously wrong, and the problem is that I can't tell what is it that you're trying to accomplish. Class-based views are extremely simple and straightforward, and it's almost never necessary to override get˙and post methods.

Why are you storing the email in the session as it can be easily retrieved from the authenticated user?

Even in your FBV you're doing to many things unnecessarily; login is best left to a separate view, redirecting the user to the right view after authentication.

Berislav Lopac
  • 16,656
  • 6
  • 71
  • 80
  • The issue i was having with the view was that it was retrieving all accounts instead of just the account of the logged in user. To fix the issue i decided to use a filter(Accounts.objects.filter(email=user's_email)) but to use the filter i needed the email variable and i wasn't sure how i could access the email variable without putting it in the url so, i decided to store it in a session and use the value in the session to run my query. In regard to getting the email from the authenticated user, how do i do that? I know login() saves the user’s ID in the session, how do i access it in my view? – Staccato Aug 08 '13 at 03:42
  • In a class-based view, the logged-in user is accessible as `self.request.user`. – Berislav Lopac Aug 08 '13 at 19:27
  • Also, the `DetailView` expects either a `pk` or a `slug` parameter in its URLConf; in this case you're probably better off simply using a `TemplateView`, as there is no need for any extra filtering. – Berislav Lopac Aug 08 '13 at 19:29
  • I tried the `self.request.user` in a get_queryset method and in the class just by itself(e.g. Accounts.object.filter(email=self.request.user)) but it didn't work. I'm aware of the pk/slug expectations but i don't want to pass these values via url. I originally did that until i discovered a security flaw...the flaw was the ability to access accounts of other users simply by passing a pk/slug in the url...of course i could've done some validations on the pk/slug to ensure it matched the currently logged in user but then what would be the point of using a generic view?!btw thanks for your help – Staccato Aug 10 '13 at 18:15
  • You don't need to use `DetailView` at all, simply use a `TemplateView` and access `request.user` in the template. You're overthinking it, try to simplify. – Berislav Lopac Aug 10 '13 at 18:57
  • Thanks for all your help but it didn't work out for me. I'll stick with FBV for my current project and perhaps revisit CBV doc later for a better understanding of how they're used and when. – Staccato Aug 11 '13 at 14:00
0

I found the answer I was looking for in this thread Django - Access session in urls.py I was definitely 'over-thinking' it and I also had no idea how to access the self.request.user. Even when I typed this solution in PyCharm editor I received a warning about request being inaccessible, probably because it's a dynamic value...below is my final solution.

#views.py
class AccountRead(ListView):
    context_object_name = 'account'
    template_name = 'accounts/view_account.html'

    def get_queryset(self):
        return Account.objects.filter(pk=self.request.user.id)
hd1
  • 33,938
  • 5
  • 80
  • 91
Staccato
  • 614
  • 1
  • 7
  • 17