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:
- 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