1

Need help or resources for Django models.

Hello, I am trying to modify/extend the django.contrib.auth.models.User class so it could register a few more fields, apart from username and password. For now I have implemented the User class only as a foreign key in another Task class.

from django.db import models
from django.contrib.auth.models import User

# Create your models here.

class Task(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) # cascade deletes all tasks/items when user is deleted
    title = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    complete = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self) :
        return self.title

    
    class Meta:
        ordering = ['complete']

What I tried:

I've tried making it a One-to-One relation with a Employee class, but things got a little messy, as I was required to first register the user, and then later add attributes to the Employee as well as selecting the (already created) User as a primary key. That was not practical I suppose.

So my question is:

What is the best way to add attributes like Email, ID number, First name, Last name, etc in the User class and how to implement/render the appropriate form in the views.py?

Here is my views.py file:

from django.contrib.auth.mixins import LoginRequiredMixin   # settings.py modification requried as following:
                                                            # add line: LOGIN_URL = 'login' above STATIC_URL field on line 120

from django.contrib.auth.forms import UserCreationForm      # for registration
from django.contrib.auth import login

from .models import Task

# Create your views here.
class CustomLoginView(LoginView):
    template_name = 'base/login.html'
    fields = '__all__'
    redirect_authenticated_user = True

    def get_success_url(self):           
        return reverse_lazy('tasks')    # Redirects to the homepage


class RegisterPage(FormView):
    template_name = 'base/register.html'
    form_class = UserCreationForm
    redirect_authenticated_user = True 
    success_url = reverse_lazy('tasks')

    def form_valid(self, form):
        user = form.save()
        if user is not None:
            login(self.request, user)
        return super(RegisterPage, self).form_valid(form)

    def get(self, *args, **kwargs):
        if self.request.user.is_authenticated:
            return redirect('tasks')
        
        return super(RegisterPage, self).get(*args, **kwargs)


class TaskList(LoginRequiredMixin ,ListView):
    model = Task 
    context_object_name = 'tasks'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['tasks'] = context['tasks'].filter(user=self.request.user)    # returns tasks from that user o.O
        context['count'] = context['tasks'].filter(complete=False).count()

        search_input = self.request.GET.get('search-area') or ''
        if search_input:
            context['tasks'] = context['tasks'].filter(title__icontains=search_input)

        context['search_input'] = search_input

        return context


class TaskDetail(LoginRequiredMixin, DetailView):      # LoginRequiredMixin has to be added for security
    model = Task 
    context_object_name = 'task'
    template_name = 'base/task.html'


class TaskCreate(LoginRequiredMixin, CreateView):
    model = Task
    fields = ['title', 'description', 'complete']
    success_url = reverse_lazy('tasks')

    def form_valid(self, form):
        form.instance.user = self.request.user 
        return super(TaskCreate, self).form_valid(form)


class TaskUpdate(LoginRequiredMixin, UpdateView):
    model = Task
    fields = ['title', 'description', 'complete']
    success_url = reverse_lazy('tasks')


class TaskDelete(LoginRequiredMixin, DeleteView):
    model = Task
    context_object_name = 'task'
    success_url = reverse_lazy('tasks')

and my file structure:

.
├── base
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0002_user.py
│   │   ├── 0003_delete_user.py
│   │   └── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── base
│   │       ├── login.html
│   │       ├── register.html
│   │       ├── task.html
│   │       ├── task_confirm_delete.html
│   │       ├── task_form.html
│   │       └── task_list.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── manage.py
└── todo_list
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Thanks in advance! :)

  • 3
    you can see this article ,maybe it will help: [link](https://testdriven.io/blog/django-custom-user-model/) – Ahmad Akel Omar Nov 29 '21 at 01:59
  • Does this answer your question? [Extending the User model with custom fields in Django](https://stackoverflow.com/questions/44109/extending-the-user-model-with-custom-fields-in-django) – funnydman Nov 29 '21 at 14:24

1 Answers1

0

You can inherit from the User model you are using or the AbstractUser model and create your own user model with as many fields as you like

ashutosh singh
  • 511
  • 3
  • 15