I have many models for very different things. Now I have added user authentication with django-allauth. What I want to do is to make all models user dependent. I mean that only the user can see their own model data that they have stored. What is the best way to achieve this? Do I need to add a ForeignKey to each model I have?
model.py:
class images(models.Model):
...
class things(models.Model):
...
class devices(models.Model):
...
class messages(models.Model):
...
#and so on...
Do I need to add a
ForeignKey
to each model I have?
Yes, but you do not have to alter all models, you can work with an abstract base model:
from django.conf import settings
class OwnedModel(models.Model):
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
class Meta:
abstract = True
and then use it in all subclasses:
class Image(OwnedModel, models.Model):
# …
pass
class Thing(OwnedModel, models.Model):
# …
pass
class Device(OwnedModel, models.Model):
# …
pass
class Message(OwnedModel, models.Model):
# …
pass
In your views you will have to filter on the user. On class-based views, you can probably do this easily with a mixin:
from django.contrib.auth.mixins import LoginRequiredMixin
class OwnedMixin(LoginRequiredMixin):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
owner=self.request.user
)
def form_valid(self, form):
form.instance.owner = self.request.user
return super().form_valid(form)
This mixin can also be used for the CreateView
and UpdateView
to automatically set the owner for the created/updated objects.
then you can use these in ListView
s, DetailView
s, etc.:
class ImageListView(OwnedMixin, ListView):
# …
class DeviceDetailView(OwnedMixin, DetailView):
# …
class ThingCreateView(OwnedMixin, CreateView):
# …