Ron Raney
Ron Raney

Reputation: 380

Django Authentication - Filter only user-created (not all) records in View

I am using Python 3.6 and Django 1.11

I have a working app (for learning purposes) that authenticates users, then allows the user to create "things" in a Django form, based on a model. In this case, users can "quit" something, like smoking or drinking, and specify their Quit Date, etc. The home page currently displays a list of all "things" created by ALL users. Anybody in the world can view these.

What I'd like to do is limit this View so that 1) only authenticated users can view 'things' from the database, and 2) authenticated users can view ONLY their "things".

How I imagine this would be accomplished is starting in the app/views.py file. Cuurently, the home page view (a list of all things) looks like this:

def something_list(request):
    things = Thing.objects.filter(quit_date__lte=timezone.now()).order_by('quit_date')
    return render(request, 'quit/something_list.html', {'things': things})

This defines a View which orders by 'quit date', and sends it to my 'something list' template.

By searching online, it seems possible to specify only seeing the user's data by adding a parameter to the Thing.objects.filter(). Everything I have tried thus far is causing errors, including this:

things = Thing.objects.filter(owner=request.user).filter(...)

and this

things = Thing.objects.filter(owner=request.user, quit_date__lte=timezone.now()).order_by('quit_date')

Here is my model, just so you know the field names:

class Thing(models.Model):
    quitter = models.ForeignKey('auth.User')
    title = models.CharField(max_length=200)
    quit_date = models.DateTimeField(default=timezone.now)
    cost_per_day = models.DecimalField(max_digits=6, decimal_places=2)
    notes = models.TextField()

Once again, I'm trying to figure out how to modify my view (above) so that authenticated users see ONLY the 'things' that they have created. Also, I want unauthorized users to see NONE of the 'things'. Hopefully, both can be accomplished with the same line of code.

Thanks in advance. I'm a beginner. Please let me know if more info is needed for an answer.

UPDATE: (solution) The solutions offered by others below are correct. Here is the line of code that works for me:

things = Thing.objects.filter(quitter=request.user).filter(quit_date__lte=timezone.now()).order_by('quit_date')

When I made this change, I got an 'AnonymousUser' object error. I needed to sort out my default view for unauthenticated users. If a user is logged in, they now see only their data, but if an anonymous user views this page, they got an error. I added an "if, else" conditional to my view to handle this. It now seems to be working and I thought I'd share my entire view, in case it might help someone.

def something_list(request):    
if request.user.is_authenticated:
    things = Thing.objects.filter(quitter=request.user).filter(quit_date__lte=timezone.now()).order_by('quit_date')
    return render(request, 'quit/something_list.html', {'things': things})
else: 
    return render(request, 'quit/base.html')

Upvotes: 0

Views: 1704

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599630

Your field is called quitter, not owner.

Thing.objects.filter(quitter=request.user, ....)

For future reference, when you get errors, you should post them in the question.

Upvotes: 1

Related Questions