get only models created by specific user

I have the code bellow and i need that every QuerySet returns only models that are created by specific user. Has a way to do it for every single queryset?

class BankListView(ListView):
    template_name = 'bank_account/pages/banks.html'
    model = BankAccountModel
    context_object_name = 'banks'

    def get_queryset(self):
        qs = super().get_queryset()
        f_qs = qs
        f_qs = BankAccountModel.objects.select_related().filter(
            id_titular_user=self.request.user)
        return f_qs

Please ignore the .select_related(), i was testing it.

Welcome @leonardoapretti !

Not “automatically”, and not by default. Regardless of the method being used, it’s still going to be up to you to ensure that your requirements are being followed.

You can create a custom manager that does add the required filter on each request, but it’s still up to you to ensure that that manager is being used, and that there aren’t any queries being written to bypass it. (See Managers | Django documentation | Django for more information about model managers.)

f_qs seems redundant. A little excess use of memory. Why not simply … ?:

    qs = super().get_queryset()
    qs = BankAccountModel.objects.select_related().filter(
        id_titular_user=self.request.user
    )
    return qs

About limiting the selection to a specific user. I assume the user is the person viewing the listed models (the current user). If you could do …

    qs = super().get_queryset()
    qs = qs.filter(pk=self.request.user.id)
    return qs

otherwise you need to deduce the id of the required user and use that to filter the queryset. Notice that you do not need to read the data from the database again because super().get_queryset() grabbed everything before. So, you only need to filter that

    qs = qs.filter(pk=deduced_id)

Thanks for the answer my friend.

Hello boss, thank you for the answer.

Do i have access to the user id in models?

The fields in the model that i use the manager are considered foreign keys?

Yes, if you pass it in as a parameter to your call to the manager method.

Again - this isn’t something that Django does for you automatically. It’s going to be up to you to make this work as desired.

We took a slightly different approach.

We use CBVs, but not (directly) the Django-provided CBVs. We’ve created our own CBV child classes that are based on the Django CBVs, but implement our own custom get_queryset method that applies our security layer to all queries.

At the moment my code is like this:

Models:

class BankAccountModel(models.Model):
    id = models.AutoField(primary_key=True, editable=False)
    id_titular_user = models.ForeignKey(
        User, verbose_name='Usuario', on_delete=models.CASCADE, default='')
    title = models.CharField(verbose_name='Titulo', max_length=65)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'Bank account'


class CardModel(models.Model):
    id = models.AutoField(primary_key=True, editable=False)
    id_bank_account = models.ForeignKey(
        BankAccountModel, on_delete=models.CASCADE, verbose_name='Banco', related_name='cartoes', default=None, null=True)
    card_name = models.CharField(
        verbose_name='Nome do cartão', max_length=65)
    payment_day = models.IntegerField(verbose_name='Dia vencimento', default=5)

    def __str__(self):
        return self.card_name

    class Meta:
        verbose_name = 'Card'

View:

class CardFormView(FormView):
    template_name = 'bank_account/pages/new_card.html'
    form_class = CardForm
    context_object_name = 'form'
    success_url = reverse_lazy('bank_account:new_card')

    #  passa argumentos para o form
    def get_form_kwargs(self):

        kwargs = super(CardFormView, self).get_form_kwargs()

        kwargs['user'] = self.request.user

        return kwargs

    def form_valid(self, form):
        cards_len = len(CardModel.objects.filter(
            id_bank_account__id_titular_user=self.request.user))

        card = form.save(commit=False)
        if cards_len == 0:
            card.principal = True

        card.save()
        messages.success(self.request, 'Cartão cadastrato!')
        return super().form_valid(card)

At this point i’m sending the current user to CardFormView to filter only banks registered by the user, as we see below:

CardForm:

class CardForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        super(CardForm, self).__init__(*args, **kwargs)
        for visible in self.visible_fields():
            input_type = visible.field.widget.__class__.__name__
            match input_type:
                case 'Select':
                    visible.field.widget.attrs['class'] = 'custom-select'
                case _:
                    visible.field.widget.attrs['class'] = 'form-control'

        # recupera o usuário passado como parâmetro na view e recupera apenas os bancos que o usuário cadastrou
        self.user = user
        self.fields['id_bank_account'].queryset = BankAccountModel.objects.filter(
            id_titular_user=self.user)

    class Meta:
        model = CardModel
        fields = '__all__'

    def clean_id_bank_account(self):
        cleaned_bank_account = self.cleaned_data['id_bank_account']
        if cleaned_bank_account == None:
            raise ValidationError('O banco não pode ser vazio.', 'invalid')

        return cleaned_bank_account

If you can show me how to do this i’ll be very grateful.