Unable to assign a user to a Form field through request.user

I want to pass the logged user to a Django Form so it can be saved on submit (request.POST)

Let’s start by getting some context.

I’m building a password manager website. In my Django project, I have three apps:

  • Accounts (has User Model)
  • Credentials (has Credential Model)
  • Websites (has Website Model)

Accounts Model:

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    def __str__(self):
        return self.username


Credential Model:

from django.db import models
from django.urls import reverse

from websites.models import Website


class Credential(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    added_on = models.DateTimeField(auto_now=True)
    website = models.ForeignKey(Website, on_delete=models.CASCADE, related_name='credentials')

    def get_absolute_url(self):
        return reverse('credential_detail', kwargs={'pk': self.pk})

    def __str__(self):
        return f'{self.username} credential'

Website Model:

from django.db import models
from django.urls import reverse

from accounts.models import User


class Website(models.Model):
    url = models.URLField(max_length=64)
    name = models.CharField(max_length=64, blank=True, null=True)
    description = models.CharField(max_length=256, blank=True, null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='websites')

    def get_absolute_url(self):
        return reverse('website_detail', kwargs={'pk': self.pk})
    
    def __str__(self):
        return self.name

The defined relationships are:

  • Many-to-one (Credential - Website)
  • Many-to-one (Website - User)

Relevant Form

from django import forms

from accounts.models import User


class WebsiteCreateForm(forms.Form):
    url = forms.URLField(max_length=64)
    name = forms.CharField(max_length=64)
    description = forms.CharField(max_length=256)
    user = forms.ModelChoiceField(queryset=None)

    def __init__(self, *args, user=None, **kwargs):
        self.user.queryset = User.objects.filter(id=user.id) if user else None
        super().__init__(*args, **kwargs)
    

Relevant Views

from django.views import View
from websites.models import Website


class WebsiteCreateView(View):
    form_class = WebsiteCreateForm
    template_name = 'websites/create_view.html'
    
    def get(self, request):
        context = {'form': self.form_class(user=request.user)}
        return render(request, self.template_name, context)
    
    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            print(form.cleaned_data)
        context = {'form': self.form_class(user=request.user)}
        return render(request, self.template_name, context)

When rendering the template, I get the following error

AttributeError at /websites/create/
'WebsiteCreateForm' object has no attribute 'user'

What am I trying to achieve here?
To pass the logged user to the form so It can be automatically assigned to the Website object that will be created.
Adding the logged user without displaying the user field in the form will be even better.

Does someone know how to accomplish this?
If you have doubts about the code or the logic, feel free to ask.

See the docs for the save method, particularly the second example block. (You can ignore the bit about the many-to-many field.)

Also, I’m guessing that WebsiteCreateForm is supposed to be a Model form? If not, then it’s still your responsibility to copy those field to the relevent models to be saved. A standard form doesn’t have anything to save data to.