Home > database >  ERROR: TypeError at /admin/myapp/booking/19/change/
ERROR: TypeError at /admin/myapp/booking/19/change/

Time:06-11

I've created a model using an abstract user model class for Online flight ticket booking. I'm new to this so haven't added many functionalities to it. I'm sharing my model.py, admin.py, serializer.py, views.py.

My question:

  1. In the link below shows a screenshot of an error occurring while I want to GET PUT DELETE booking data using ADMIN panel. I'm not able to figure out the problem yet.

Error while trying to GET PUT DELETE booking

#models.py


import email
from pyexpat import model
from django.db import models
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver

from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)

GENDER_CHOICES = (
    (0, 'male'),
    (1, 'female'),
    (2, 'not specified'),)

class UserManager(BaseUserManager):
  def create_user(self, email, name,contact_number,gender,address,state,city,country,pincode,dob ,password=None, password2=None):
      
      if not email:
          raise ValueError('User must have an email address')

      user = self.model(
          email=self.normalize_email(email),
          name=name,
          contact_number=contact_number,
          gender=gender,
          address=address,
          state=state,
          city=city,
          country=country,
          pincode=pincode,
          dob=dob,
          
      )

      user.set_password(password)
      
      user.save(using=self._db)
      return user

  def create_superuser(self, email, name,contact_number,gender,address,state,city,country,pincode,dob , password=None):
     
      user = self.create_user(
          email,
          
          name=name,
          contact_number=contact_number,
          gender=gender,
          address=address,
          state=state,
          city=city,
          country=country,
          pincode=pincode,
          dob=dob,
          password=password,
          
      )
      user.is_admin = True
      user.save(using=self._db)
      return user



class User(AbstractBaseUser):
    email = models.EmailField(verbose_name='Email',max_length=255,unique=True)
    name = models.CharField(max_length=200)
    contact_number= models.IntegerField()
    gender = models.IntegerField(choices=GENDER_CHOICES)
    address= models.CharField(max_length=100)
    state=models.CharField(max_length=100)
    city=models.CharField(max_length=100)
    country=models.CharField(max_length=100)
    pincode= models.IntegerField()
    dob = models.DateField()


    # is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name','contact_number','gender','address','state','city','country','pincode','dob']

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return self.is_admin

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin


# Create your models here.
class Airport(models.Model):
    Airport_name=models.CharField(max_length=100)
    country=models.CharField(max_length=100)

    def __str__(self):
        return self.Airport_name

class Flight(models.Model):

    flight_number = models.CharField(max_length=100,unique=True)
    depart_date_time = models.DateTimeField(auto_now_add=True)
    arrival_date_time = models.DateTimeField(auto_now_add=True)
    origin = models.CharField(max_length=100, blank=True, default='')
    destination = models.CharField(max_length=100, blank=True, default='')
    price = models.IntegerField()
    airline_name = models.CharField(max_length=100, blank=True, default='')
    total_seats = models.IntegerField()
    available_seats =  models.IntegerField()
    
    
    airport=models.ForeignKey(Airport,on_delete=models.CASCADE)

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

   

class Passenger(models.Model):
    name = models.CharField(max_length=100,blank=True, default='')
    contact_number= models.IntegerField()
    email = models.EmailField(max_length=254)
    
    gender = models.IntegerField(choices=GENDER_CHOICES)
    age= models.IntegerField()
    user=models.ForeignKey(User,on_delete=models.CASCADE)

    def __str__(self):
        return self.name  


class Booking(models.Model):
    user =models.ForeignKey(User,on_delete=models.CASCADE)
    flights =models.ForeignKey(Flight,on_delete=models.CASCADE)
    passenger =models.ManyToManyField(Passenger)
    booking_number= models.CharField(max_length= 100,default=0, blank= True)
    booking_time = models.DateTimeField(auto_now_add=True)
    no_of_passengers= models.IntegerField(default=0, blank= True)

    def __str__(self):
        return self.booking_number


Corresponding serializer

#serializers.py


from rest_framework import serializers
from myapp.models import Airport, Flight, User, Passenger, Booking 


class UserRegistrationSerializer(serializers.ModelSerializer):
  # We are writing this becoz we need confirm password field in our Registratin Request
  password2 = serializers.CharField(style={'input_type':'password'}, write_only=True)
  class Meta:
    model = User
    fields=['email','name','contact_number','gender','address','state','city','country','pincode','dob','password', 'password2']
    extra_kwargs={
      'password':{'write_only':True}
    }

  # Validating Password and Confirm Password while Registration
  def validate(self, attrs):
    password = attrs.get('password')
    password2 = attrs.get('password2')
    if password != password2:
      raise serializers.ValidationError("Password and Confirm Password doesn't match")
    return attrs

  def create(self, validate_data):
    return User.objects.create_user(**validate_data)

class UserLoginSerializer(serializers.ModelSerializer):
  email = serializers.EmailField(max_length=255)
  class Meta:
    model = User
    fields = ['email', 'password']

# class UserProfileSerializer(serializers.ModelSerializer):
#   class Meta:
#     model = User
#     fields = '__all__'



class AirportSerializer(serializers.ModelSerializer):
    class Meta:
        model = Airport
        fields = '__all__'

class FlightSerializer(serializers.ModelSerializer):
    class Meta:
        model = Flight
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model= User
        fields = '__all__'

class PassengerSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=False)
    class Meta:
        model= Passenger
        fields = '__all__'

class BookingSerializer(serializers.ModelSerializer):
    class Meta:
        model= Booking
        fields = '__all__'


    

#admin.py

from django.contrib import admin
from .models import Airport, Booking, Flight, User, Passenger


from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

class UserModelAdmin(BaseUserAdmin):
  # The fields to be used in displaying the User model.staff= models.BooleanField(default=False)
  # These override the definitions on the base UserModelAdmin
  # that reference specific fields on auth.User.
  list_display = ('id', 'email', 'name', 'is_admin','is_active')
  list_filter = ('is_admin',)
  fieldsets = (
      ('User Credentials', {'fields': ('email', 'password')}),
      ('Personal info', {'fields': ('name', 'contact_number', 'gender', 'dob','address', 'state', 'city', 'country', 'pincode',)}),
      ('Permissions', {'fields': ('is_admin',)}),
  )
  # add_fieldsets is not a standard ModelAdmin attribute. UserModelAdmin
  # overrides get_fieldsets to use this attribute when creating a user.
  add_fieldsets = (
      (None, {
          'classes': ('wide',),
          'fields': ('email', 'name', 'password1', 'password2',),
      }),
  )
  search_fields = ('email',)
  ordering = ('email', 'id')
  filter_horizontal = ()



# Register your models here.
admin.site.register(User,UserModelAdmin)
admin.site.register([Airport,Flight,Passenger,Booking])

#views.py



from django.shortcuts import render
from django.http import Http404, JsonResponse
#from django.http import HttpResponse, JsonResponse
from rest_framework.views import APIView
from rest_framework.response import Response
#from rest_framework.parsers import JSONParser
from django.contrib.auth import authenticate
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import SAFE_METHODS, BasePermission,IsAuthenticatedOrReadOnly,IsAuthenticated, IsAdminUser, DjangoModelPermissionsOrAnonReadOnly, DjangoModelPermissions
from myapp.renderers import UserRenderer
from rest_framework import status
from rest_framework import permissions
from rest_framework import generics
from myapp.models import Airport, Flight, User, Passenger, Booking
from myapp.serializers import *
from myapp.permissions import IsOwnerOrAdmin
from rest_framework import viewsets



def get_tokens_for_user(user):
  refresh = RefreshToken.for_user(user)
  return {
      'refresh': str(refresh),
      'access': str(refresh.access_token),
  }



# Create your views here.

class UserRegistrationView(APIView):
  renderer_classes = [UserRenderer]
  def post(self, request, format=None):
    serializer = UserRegistrationSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    user = serializer.save()
    token = get_tokens_for_user(user)
    return Response({'token':token, 'msg':'Registration Successful'}, status=status.HTTP_201_CREATED)

class UserLoginView(APIView):
  renderer_classes = [UserRenderer]
  def post(self, request, format=None):
    serializer = UserLoginSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    email = serializer.data.get('email')
    password = serializer.data.get('password')
    user = authenticate(email=email, password=password)
    if user is not None:
      token = get_tokens_for_user(user)
      return Response({'token':token, 'msg':'Login Success'}, status=status.HTTP_200_OK)
    else:
      return Response({'errors':{'non_field_errors':['Email or Password is not Valid']}}, status=status.HTTP_404_NOT_FOUND)


class UserProfileView(APIView):
  renderer_classes = [UserRenderer]
  permission_classes = [IsAuthenticated]
  def get(self, request, format=None):
    serializer = UserSerializer(request.user)
    return Response(serializer.data, status=status.HTTP_200_OK)


class UserListCreateAPIView(generics.ListCreateAPIView):
    permission_classes = [IsAdminUser]
    queryset = User.objects.all()
    serializer_class = UserSerializer

class UserRetrtieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
    
    queryset = User.objects.all()
    serializer_class = UserSerializer

    








class FlightListCreateAPIView(generics.ListCreateAPIView):
    
    queryset = Flight.objects.all()
    serializer_class = FlightSerializer
    
    permission_classes= [DjangoModelPermissions]


class FlightRetrtieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
    
    queryset = Flight.objects.all()
    serializer_class = FlightSerializer

class AirportListCreateAPIView(generics.ListCreateAPIView):
    queryset = Airport.objects.all()
    serializer_class = AirportSerializer

class AirportRetrtieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
    
    queryset = Airport.objects.all()
    serializer_class = AirportSerializer





class PassengerListCreateAPIView(generics.ListCreateAPIView):
    queryset = Passenger.objects.all()
    serializer_class = PassengerSerializer

class PassengerRetrtieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Passenger.objects.all()
    serializer_class = PassengerSerializer



class BookingRetrtieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Booking.objects.all()
    serializer_class = BookingSerializer



class BookViewSet(viewsets.ModelViewSet):
    
    # queryset = Book.objects.all()
    serializer_class = BookingSerializer
    # print(serializer_class)
    def get_queryset(self):
        book = Booking.objects.all()
        return book 

    def create(self, request, *args, **kwargs):
        data = request.data

        user = User.objects.get(id=data["user"])
        flightdetails = Flight.objects.get(id=data["flights"])
        # bookingdetails = Booking.objects.get(no_of_passengers=data["no_of_passengers"])

        
        new_book = Booking.objects.create(
            booking_number= data["booking_number"],
            no_of_passengers= data["no_of_passengers"],
            user=user,
            flights=flightdetails,
        )
        new_book.save()
        for passenger in data["passenger"]:
            passenger_book= Passenger.objects.create(
                user = user,
                name= passenger["name"],
                contact_number = passenger["contact_number"],
                email = passenger["email"],
                gender = passenger["gender"],
                age = passenger["age"]

            )
            new_book.passenger.add(passenger_book)

            if flightdetails.available_seats < len(data["passenger"]):
                return Response({"data": "No seats available", "status": status.HTTP_400_BAD_REQUEST})
            update_seats = flightdetails.available_seats - data["no_of_passengers"]
            flightdetails.available_seats = update_seats
            flightdetails.save()
            serializers = BookingSerializer(new_book)
            return Response({"data": serializers.data, "status": status.HTTP_201_CREATED})


#urls.py

from django.urls import path, include
from myapp.views import *
from rest_framework import routers





router = routers.DefaultRouter()
router.register('booking', BookViewSet, basename='MyModel')
urlpatterns = [

    path('register/', UserRegistrationView.as_view(), name='register'),
    path('login/', UserLoginView.as_view(), name='login'),
    path('profile/', UserProfileView.as_view(), name='profile'),
    path('flight/', FlightListCreateAPIView.as_view()),
    path('flight_info/<int:pk>/', FlightRetrtieveUpdateDestroyAPIView.as_view()),
    path('customer/', UserListCreateAPIView.as_view()),
    path('customer_info/<int:pk>/', UserRetrtieveUpdateDestroyAPIView.as_view()),
    path('passenger/', PassengerListCreateAPIView.as_view()),
    path('passenger_info/<int:pk>/', PassengerRetrtieveUpdateDestroyAPIView.as_view()),
    
    path('booking_info/<int:pk>/', BookingRetrtieveUpdateDestroyAPIView.as_view()),
    #path('booking/', BookingAPIView.as_view()),
    path('', include(router.urls)),
    

    
    
    
]


CodePudding user response:

The problem may be that you have migrated before having created the abstract user model.

To solve this you need to delete all your migration files and folders
Next, in your command line, in the main directory, call the migration commands:
python3 manage.py makemigrations
then
python3 manage.py migrate

  • Related