How to Manage User & Create a Model

Scenario The are two roles in the system; LIBRARIAN and MEMBER

As a User

  • I can signup either as LIBRARIAN and MEMBER using username and password
  • I can login using username/password and get JWT access token

As a Librarian

  • I can add, update, and remove Books from the system
  • I can add, update, view, and remove Member from the system

As a Member

  • I can view, borrow, and return available Books
  • Once a book is borrowed, its status will change to BORROWED
  • Once a book is returned, its status will change to AVAILABLE
  • I can delete my own account

As i’m a newbie. Please help in how can I create the models of these. Thank you

What background or work have you done so far with Django?

Have you worked your way through either the Official Django Tutorial or the Django Girls Tutorial?

Can you be more specific about the type of help you need?

What do you have so far?

Thank you sir. Actually i have completed few of the tasks but got confused. Now i’m stuck into these. Could you please help me in further process.
[TypeError: User() got unexpected keyword arguments: ‘reg_data_l’ & You may need to make the field read-only, or override the UserSerializer.create()]
Models.py

class User(AbstractUser, PermissionsMixin):
    is_admin = models.BooleanField(default=False)
    is_librarian = models.BooleanField(default=False)
    is_member = models.BooleanField(default=False)

class Librarian(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    librarian_firstname = models.CharField(max_length=20)
    librarian_middlename = models.CharField(max_length=20)
    librarian_lastname = models.CharField(max_length=20)
    CATEGORY_GENDER = (('Male','Male'),('Female','Female'))
    librarian_gender = models.CharField(max_length=6, choices=CATEGORY_GENDER)
    librarian_contact = models.CharField(max_length=10, unique=True, blank=True)
    librarian_photo = models.ImageField(upload_to = 'media/librarian_photo', default='media/default.webp', blank=True)
    librarian_address = models.CharField(max_length=100)

    def __str__(self):
        return str(self.librarian_firstname)+ ' - '+(self.librarian_lastname)
    
    def save(self, *args, **kwargs):
        for field_name in ['librarian_firstname', 'librarian_middlename', 'librarian_lastname']:
            val = getattr(self, field_name, False)
            if val:
                setattr(self, field_name, val.capitalize())
        super(Librarian, self).save(*args, **kwargs)

class Member(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    member_firstname = models.CharField(max_length=20)
    member_middlename = models.CharField(max_length=20)
    member_lastname = models.CharField(max_length=20)
    CATEGORY_GENDER = (('Male','Male'),('Female','Female'))
    member_gender = models.CharField(max_length=6, choices=CATEGORY_GENDER)
    member_contact = models.CharField(max_length=10, unique=True, blank=True)
    member_photo = models.ImageField(upload_to = 'media/member_photo', default='media/default.webp', blank=True)
    member_address = models.CharField(max_length=100)

    def __str__(self):
        return str(self.member_firstname)+ ' - '+(self.member_lastname)
    
    def save(self, *args, **kwargs):
        for field_name in ['member_firstname', 'member_middlename', 'member_lastname']:
            val = getattr(self, field_name, False)
            if val:
                setattr(self, field_name, val.capitalize())
        super(Member, self).save(*args, **kwargs)
    
class Books(models.Model):
    book_name = models.CharField(max_length=50)
    book_author = models.CharField(max_length=30)
    book_isbn = models.PositiveIntegerField()    

    def __str__(self):
        return str(self.book_name)

serializers.py

class MemberSerializer(serializers.ModelSerializer):
    class Meta:
        model = Member
        fields = ('member_firstname','member_middlename','member_lastname','member_gender',
                  'member_contact','member_photo','member_address')

class UserSerializer(serializers.ModelSerializer):
    reg_data = MemberSerializer()

    class Meta:
        model = User
        fields = ('username','password','reg_data',)

        def create(self, validated_data):
            reg_info = validated_data.pop('reg_data')
            user_reg = User.objects.create(**validated_data)

            user_reg.set_password(validated_data['password'])
            user_reg.save()

            Member.objects.create(user=user_reg, **reg_info)
            obj = User.objects.get(id=user_reg.id)
            return obj

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Books
        fields = ('book_name','book_author','book_isbn')

class LibrarianSerializer(serializers.ModelSerializer):
    class Meta:
        model = Librarian
        fields = ('librarian_firstname','librarian_middlename','librarian_lastname',
                  'librarian_gender','librarian_contact','librarian_photo','librarian_address')

class LibrarianUserSerializer(serializers.ModelSerializer):
    reg_data_l = LibrarianSerializer()

    class Meta:
        model = User
        fields = ('username','password','reg_data_l',)

        def create(self, validated_data):
            reg_info = validated_data.pop('reg_data_l')
            user_reg = User.objects.create(**validated_data)

            user_reg.set_password(validated_data['password'])
            user_reg.save()

            Librarian.objects.create(user=user_reg, **reg_info)
            obj = User.objects.get(id=user_reg.id)
            return obj

views.py

class LibrarianAPI(viewsets.ModelViewSet):
    queryset = Librarian.objects.all()
    # authentication_classes = (JWTAuthentication, )
    permission_classes = (IsAuthenticated ,)
    serializer_class = UserSerializer

class MemberAPI(viewsets.ModelViewSet):
    queryset = Member.objects.all()
    # authentication_classes = (JWTAuthentication, )
    permission_classes = (IsAuthenticated ,)
    serializer_class = UserSerializer

class BooksAPI(viewsets.ModelViewSet):
    queryset = Books.objects.all()
    # authentication_classes = (JWTAuthentication, )
    permission_classes = (IsAuthenticated ,)
    serializer_class = BookSerializer

As I have to perofrm these operations. Please help sir
As a User

  • I can signup either as LIBRARIAN and MEMBER using username and password
  • I can login using username/password and get JWT access token

As a Librarian

  • I can add, update, and remove Books from the system
  • I can add, update, view, and remove Member from the system

As a Member

  • I can view, borrow, and return available Books
  • Once a book is borrowed, its status will change to BORROWED
  • Once a book is returned, its status will change to AVAILABLE
  • I can delete my own account

Django’s permissions system is built on a Group and Permissions model.

You’ll want to read Using the Django authentication system | Django documentation | Django for all the details.

Briefly, you will want to make “Librarian” and “Member” as groups, not as flags on the User object.

You will make your individual Users members of those groups.

You assign Permissions to those Groups.

Your views then check the necessary permission for that view.

For example, you may have a view named AddBook in an app named Library. You would have a permission named library.add_book which can be tested in your views to determine whether the person making that request has that permission.

Side note: From what you’ve posted, it appears that you may be working with the Django Rest Framework. While there are some people here who are familiar with DRF, this is not one of DRF’s “officially-recognized” support channels. You may want to check out your options at Home - Django REST framework.

Thanks alot. I’ll check with the Permissions & Groups. Thank you sir for your time :slightly_smiling_face: