POST to one-to-many relationship table raise ValidationError "Unknown field." - python-3.x

I am trying to implement hospital api with to one-to-many relationship table (Subject - is Parent table, RawData - child table), with flask-api, marshmellow and flask-sqlalchemy frameworks. After implementing schemes, models and resource, I make post method with raw json, through postman in endpoint /api/upload/subject:
{
"first_name": "Johny",
"last_name": "Silverhand",
"raw_tomograms": [
{
"rawdata_id": 1,
"raw_name": "subject_1",
"path": "/srv/John_s_rawdata.zip",
"subject_id": 1
}
]
}
But get an error marshmallow.exceptions.ValidationError: {'raw_tomograms': {0: {'rawdata_id': ['Unknown field.'], 'raw_name': ['Unknown field.'], 'path': ['Unknown field.']}}}
Models:
#./api/models/subject.py:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from api.database import db
class Subject(db.Model):
__tablename__ = "subject"
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(50), nullable=True)
last_name = db.Column(db.String(50), nullable=True)
raw_tomograms = db.relationship("RawData", backref="subject", lazy=True)
create_date = db.Column(db.DateTime(timezone=True), default=datetime.now())
update_date = db.Column(db.DateTime(timezone=True), onupdate=datetime.now())
def __repr__(self):
return "<Subject {self.id} {self.first_name>"
#./api/models/rawdata.py:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from api.database import db
class RawData(db.Model):
__tablename__ = "raw_data"
id = db.Column(db.Integer, primary_key=True)
raw_name = db.Column(db.String(120), nullable=False)
path = db.Column(db.String(250))
create_date = db.Column(db.DateTime(timezone=True), default=datetime.now)
update_date = db.Column(db.DateTime(timezone=True), onupdate=datetime.now)
subject_id = db.Column(db.Integer, db.ForeignKey("subject.id"))
def __repr__(self):
return f"<Raw_data {self.id}>"
Schemas:
#./api/schemas/rawdata.py:
from marshmallow import Schema, fields, post_load, EXCLUDE
from api.models.rawdata import RawData
from api.models.subject import Subject
from api.database import db
from api.database import ma
class RawSchema(Schema):
rawdata_id = fields.Integer(),
raw_name = fields.String(),
path = fields.String(),
create_date = fields.DateTime(timezone=True)
update_date = fields.DateTime(timezone=True)
subject_id = fields.Integer()
#post_load
def make_rawdata(self, data, **kwargs):
return RawData(**data)
#./api/schemas/subjecta.py:
from marshmallow import Schema, fields, post_load
from epidetect_api.models.subject import Subject
from epidetect_api.database import db
#from epidetect_api.database import ma
from epidetect_api.schemas.rawdata_schema import RawSchema
class SubjectSchema(Schema):
"""
Subject Marshmallow Schema
Marshmallow schema used for loading/dumping Subject
"""
#raw_tomograms = ma.Nested(RawSchema, many=True)
class Meta:
model = Subject
#exclude =
id = fields.Integer(load=True, partial=True)
first_name = fields.String(allow_none=True)
last_name = fields.String(allow_none=True)
create_date = fields.DateTime(timezone=True)
update_date = fields.DateTime(timezone=True)
raw_tomograms = fields.Nested(RawSchema, many=True)
#post_load
def make_subject(self, data, **kwargs):
return Subject(**data)
Resource:
#./api/resources/subject_resource.py
import logging
from flask import request, jsonify, render_template
from flask_restful import Resource, abort
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound
import json
from api.database import db
from api.models.subject import Subject
from api.schemas.subject_schema import SubjectSchema
SUBJECTS_ENDPOINT = "/api/upload/subject"
logger = logging.getLogger(__name__)
class SubjectsResource(Resource):
def post(self):
"""
SubjectsResource POST method. Adds a new Subject to the database.
:return: Subject.id, 201 HTTP status code.
"""
subject = SubjectSchema().load(request.json)
print(request.json, flush=True)
try:
db.session.add(subject)
db.session.commit()
except IntegrityError as e:
logger.warning(
f"Integrity Error, this subject is already in the database. Error: {e}"
)
abort(500, message="Unexpected Error!")
else:
return subject.id, 201
Full error log:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 271, in error_router
return original_handler(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 271, in error_router
return original_handler(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 467, in wrapper
resp = resource(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/flask/views.py", line 84, in view
return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 582, in dispatch_request
resp = meth(*args, **kwargs)
File "/srv/api/resources/subject_resource.py", line 48, in post
subject = SubjectSchema().load(request.json)
File "/usr/local/lib/python3.7/site-packages/marshmallow/schema.py", line 720, in load
data, many=many, partial=partial, unknown=unknown, postprocess=True
File "/usr/local/lib/python3.7/site-packages/marshmallow/schema.py", line 904, in _do_load
raise exc
marshmallow.exceptions.ValidationError: {'raw_tomograms': {0: {'rawdata_id': ['Unknown field.'], 'raw_name': ['Unknown field.'], 'path': ['Unknown field.']}}}

Related

TypeError: 'type' object is not iterable - DRF

I'm making my first DRF api and I get a strange TypeError when I try to access to my data using a GET request, I get this error:
'type' object is not iterable
All working until I add the function for get the average of Reviews.mark in Movie. I not understand why Reviews and Actors are iterable and if you can explain it to me it's cool !
Here are some code snippets bellow.
models.py
from django.db import models
from django.contrib.auth import get_user_model
import datetime
User = get_user_model()
class Actor(models.Model):
name = models.CharField(max_length=255)
first_name = models.CharField(max_length=255)
class Movie(models.Model):
title = models.CharField(max_length=255)
description = models.CharField(max_length=255, default='Description')
date = models.DateTimeField(default=datetime.date.today)
created_on = models.DateTimeField(auto_now_add = True)
actors = models.ManyToManyField(Actor)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def average_reviews(self):
if hasattr(self, '_average_reviews'):
return self._average_reviews
return self.reviews.aggregate(models.Avg('mark'))
class Reviews(models.Model):
mark = models.IntegerField(default=5)
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
views.py
from django.shortcuts import render
from django.db.models import Avg
from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from .models import Movie, Actor, Reviews
from .serializers import MovieSerializer, ActorSerializer, ReviewsSerializer
# Create your views here.
class MovieViewSet(viewsets.ModelViewSet):
authentication_classes = (BasicAuthentication,)
permission_classes = (IsAuthenticated,)
serializer_class = MovieSerializer
def get_queryset(self):
return Movie.objects.all().annotate(_average_reviews=Avg('reviews__mark'))
#queryset = Movie.objects.all()
class ActorViewSet(viewsets.ModelViewSet):
authentication_classes = (BasicAuthentication)
permission_classes = (IsAuthenticated,)
serializer_class = ActorSerializer,
queryset = Actor.objects.all()
class ReviewsViewSet(viewsets.ModelViewSet):
authentication_classes = (BasicAuthentication)
permission_classes = (IsAuthenticated,)
serializer_class = ReviewsSerializer,
queryset = Reviews.objects.all()
serializers.py
from rest_framework import serializers
from .models import Movie, Actor, Reviews
class ActorSerializer(serializers.ModelSerializer):
class Meta:
model = Actor
fields = '__all__'
class ReviewsSerializer(serializers.ModelSerializer):
class Meta:
model = Reviews
fields = '__all__'
class MovieSerializer(serializers.ModelSerializer):
actors = ActorSerializer(many=True)
average_reviews = serializers.SerializerMethodField()
def get_average_reviews(self,obj):
return obj.average_reviews()
class Meta:
model = Movie
fields = '__all__'
I also leave the Traceback for more informations:
Traceback (most recent call last):
File "/home/qcouderc/.local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/qcouderc/.local/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/qcouderc/.local/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/qcouderc/.local/lib/python3.10/site-packages/rest_framework/viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "/home/qcouderc/.local/lib/python3.10/site-packages/rest_framework/views.py", line 492, in dispatch
request = self.initialize_request(request, *args, **kwargs)
File "/home/qcouderc/.local/lib/python3.10/site-packages/rest_framework/viewsets.py", line 146, in initialize_request
request = super().initialize_request(request, *args, **kwargs)
File "/home/qcouderc/.local/lib/python3.10/site-packages/rest_framework/views.py", line 394, in initialize_request
authenticators=self.get_authenticators(),
File "/home/qcouderc/.local/lib/python3.10/site-packages/rest_framework/views.py", line 272, in get_authenticators
return [auth() for auth in self.authentication_classes]
TypeError: 'type' object is not iterable
[13/Sep/2022 14:36:00] "GET /api/reviews/ HTTP/1.1" 500 16564
Thanks for your help
You should add comma after authentication class to make python understand that this is tuple:
class ActorViewSet(viewsets.ModelViewSet):
authentication_classes = (BasicAuthentication,)
Or you can just use list:
class ActorViewSet(viewsets.ModelViewSet):
authentication_classes = [BasicAuthentication]

Flask-login AttributeError: 'str' object has no attribute 'is_active'

Hello im trying to build db management site but when i try to login correctly it refers to AttributeError: 'str' object has no attribute 'is_active' i already added UserMixin in my models.py but still the problem still persist.
App.py:
def config_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///db/bogus.db"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'admin.index'
login_manager.init_app(app)
bootstrap = Bootstrap4(app)
#login_manager.user_loader
def load_user(user_id):
return Admin.query.get(int(id))
app.register_blueprint(find, url_prefix='/')
app.register_blueprint(admin, url_prefix='/admin')
app.register_blueprint(gateway, url_prefix='/api')
return app
Routes.py
#admin.route('/', methods=['GET'])
def index():
form = admin_login()
return render_template('login.html', form=form)
#admin.route('/', methods=['POST'])
def index_post():
form = admin_login()
user = form.name.data
password = form.password.data
remember = form.remember.data
user_check = Admin.query.filter_by(username=user).first()
if user_check:
password_check = check_password_hash(user_check.password, password)
if password_check:
login_user(user)
return redirect(url_for('admin.search'))
Models.py
class Admin(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(50), unique=True)
password = db.Column(db.String(80))
Error log
Traceback (most recent call last):
File "/home/vee/.local/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "/home/vee/.local/lib/python3.9/site-packages/flask/app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "/home/vee/.local/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/home/vee/.local/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/vee/.local/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/home/vee/.local/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/vee/beta-app/admin/routes.py", line 30, in index_post
login_user(user)
File "/home/vee/.local/lib/python3.9/site-packages/flask_login/utils.py", line 166, in login_user
if not force and not user.is_active:
AttributeError: 'str' object has no attribute 'is_active'

no such table: users_user

I need to create POST method Registration Form i have this code (i am using django rest_framework):
Users.models
class User(AbstractBaseUser):
username = models.CharField(max_length=20, unique=True)
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELD = 'username'
class MyUserManager(CreateAPIView):
def post(request, *args, **kwargs):
username = request.data.get('username')
email = request.data.get('email')
password = request.data.get('password')
user = model(username=username, email=normalize_email(email))
user.set_password(password)
return user
users.serializers:
class MyUserManagerSerializers(serializers.ModelSerializer):
username = serializers.CharField(max_length=20)
email = serializers.EmailField()
password = serializers.CharField()
class Meta:
model = models.User
fields = ['email', 'username', 'password']
and models.views.py:
class UserManagerAPIView(ListCreateAPIView):
serializer_class = MyUserManagerSerializers
def UserRegistration(request):
user = UserManager.post(request)
serializers = MyUserManagerSerializers(user)
serializers.is_valid(raise_exception=True)
serializers.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
urls.py
urlpatterns = [
path('register', UserManagerAPIView.as_view()),
and installed_apps:
INSTALLED_APPS = ['users.apps.UsersConfig']
AUTH_USER_MODEL = 'users.User'
when i am send POST method to localhost:8000/register i always get error:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
The above exception (no such table: users_user) was the direct cause of the following exception:
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/rest_framework/generics.py", line 242, in post
return self.create(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 19, in create
self.perform_create(serializer)
File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 24, in perform_create
serializer.save()
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 205, in save
self.instance = self.create(validated_data)
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 939, in create
instance = ModelClass._default_manager.create(**validated_data)
File "/usr/local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 453, in create
obj.save(force_insert=True, using=self.db)
File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/base_user.py", line 67, in save
super().save(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 763, in save_base
updated = self._save_table(
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 868, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 906, in _do_insert
return manager._insert(
File "/usr/local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1416, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/debug_toolbar/panels/sql/tracking.py", line 198, in execute
return self._record(self.cursor.execute, sql, params)
File "/usr/local/lib/python3.9/site-packages/debug_toolbar/panels/sql/tracking.py", line 133, in _record
return method(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
Exception Type: OperationalError at /register
Exception Value: no such table: users_user
I am new in django, but i checked docs, check stack overflow, checked othe forums and can't to find how to fix this error, may be it is my bad. Because i think my register form is so bad, but how can i fix this? I did all migrations, and always i see "succesfully!".
In your User model:
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
class UserManager(BaseUserManager):
# You have to override the usermanager!
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, username=email, **extra_fields) # Here I set the email as the username!
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email=None, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email=None, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
class CustomUser(AbstractUser):
email = models.EmailField('Email', unique=True)
USERNAME_FIELD = 'email' # Again!
REQUIRED_FIELD = ['first_name', 'last_name', ] # Here you can add the fields that you want or the fields that you maybe create!
def __str__(self):
return self.email
objects = UserManager()
In your admin.py:
from django.conf import settings
from django.contrib import admin, messages
from django.contrib.admin.options import IS_POPUP_VAR
from django.contrib.admin.utils import unquote
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import (
AdminPasswordChangeForm,
)
from .models import CustomUser # Here! You have to import your User not the default user!
from .forms import CustomUserCreationForm, CustomUserChangeForm # Import the forms tha you create and set bellow!
from django.core.exceptions import PermissionDenied
from django.db import router, transaction
from django.http import Http404, HttpResponseRedirect
from django.template.response import TemplateResponse
from django.urls import path, reverse
from django.utils.decorators import method_decorator
from django.utils.html import escape
from django.utils.translation import gettext, gettext_lazy as _
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
csrf_protect_m = method_decorator(csrf_protect)
sensitive_post_parameters_m = method_decorator(sensitive_post_parameters())
#admin.register(User)
class UserAdmin(admin.ModelAdmin):
add_form_template = 'admin/auth/user/add_form.html'
change_user_password_template = None
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
form = CustomUserChangeForm
add_form = CustomUserCreationForm
change_password_form = AdminPasswordChangeForm
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
filter_horizontal = ('groups', 'user_permissions',)
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super().get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during user creation
"""
defaults = {}
if obj is None:
defaults['form'] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
def get_urls(self):
return [
path(
'<id>/password/',
self.admin_site.admin_view(self.user_change_password),
name='auth_user_password_change',
),
] + super().get_urls()
def lookup_allowed(self, lookup, value):
# Don't allow lookups involving passwords.
return not lookup.startswith('password') and super().lookup_allowed(lookup, value)
#sensitive_post_parameters_m
#csrf_protect_m
def add_view(self, request, form_url='', extra_context=None):
with transaction.atomic(using=router.db_for_write(self.model)):
return self._add_view(request, form_url, extra_context)
def _add_view(self, request, form_url='', extra_context=None):
# It's an error for a user to have add permission but NOT change
# permission for users. If we allowed such users to add users, they
# could create superusers, which would mean they would essentially have
# the permission to change users. To avoid the problem entirely, we
# disallow users from adding users if they don't have change
# permission.
if not self.has_change_permission(request):
if self.has_add_permission(request) and settings.DEBUG:
# Raise Http404 in debug mode so that the user gets a helpful
# error message.
raise Http404(
'Your user does not have the "Change user" permission. In '
'order to add users, Django requires that your user '
'account have both the "Add user" and "Change user" '
'permissions set.')
raise PermissionDenied
if extra_context is None:
extra_context = {}
username_field = self.model._meta.get_field(self.model.USERNAME_FIELD)
defaults = {
'auto_populated_fields': (),
'username_help_text': username_field.help_text,
}
extra_context.update(defaults)
return super().add_view(request, form_url, extra_context)
#sensitive_post_parameters_m
def user_change_password(self, request, id, form_url=''):
user = self.get_object(request, unquote(id))
if not self.has_change_permission(request, user):
raise PermissionDenied
if user is None:
raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {
'name': self.model._meta.verbose_name,
'key': escape(id),
})
if request.method == 'POST':
form = self.change_password_form(user, request.POST)
if form.is_valid():
form.save()
change_message = self.construct_change_message(request, form, None)
self.log_change(request, user, change_message)
msg = gettext('Password changed successfully.')
messages.success(request, msg)
update_session_auth_hash(request, form.user)
return HttpResponseRedirect(
reverse(
'%s:%s_%s_change' % (
self.admin_site.name,
user._meta.app_label,
user._meta.model_name,
),
args=(user.pk,),
)
)
else:
form = self.change_password_form(user)
fieldsets = [(None, {'fields': list(form.base_fields)})]
adminForm = admin.helpers.AdminForm(form, fieldsets, {})
context = {
'title': _('Change password: %s') % escape(user.get_username()),
'adminForm': adminForm,
'form_url': form_url,
'form': form,
'is_popup': (IS_POPUP_VAR in request.POST or
IS_POPUP_VAR in request.GET),
'add': True,
'change': False,
'has_delete_permission': False,
'has_change_permission': True,
'has_absolute_url': False,
'opts': self.model._meta,
'original': user,
'save_as': False,
'show_save': True,
**self.admin_site.each_context(request),
}
request.current_app = self.admin_site.name
return TemplateResponse(
request,
self.change_user_password_template or
'admin/auth/user/change_password.html',
context,
)
def response_add(self, request, obj, post_url_continue=None):
"""
Determine the HttpResponse for the add_view stage. It mostly defers to
its superclass implementation but is customized because the User model
has a slightly different workflow.
"""
# We should allow further modification of the user just added i.e. the
# 'Save' button should behave like the 'Save and continue editing'
# button except in two scenarios:
# * The user has pressed the 'Save and add another' button
# * We are adding a user in a popup
if '_addanother' not in request.POST and IS_POPUP_VAR not in request.POST:
request.POST = request.POST.copy()
request.POST['_continue'] = 1
return super().response_add(request, obj, post_url_continue)
Create a forms.py and add:
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ('email', )
labels = {'username': 'Username/Email'}
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.email = self.cleaned_data['username']
if commit:
user.save()
return user
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email', )
That's it!
run command
python manage.py makemigrations users

Flask error 500 Internal Server Error. Firebase-authentication with email/password

I am trying to implement firebase authentication with email and password on my flask app. I am getting this error when I try to login or register.
Any help would be appreciated.
I am very new to coding so please ELI5 if possible. Any pointers on how to improve anything else on my code would be appreciated.
127.0.0.1 - - [18/Jul/2021 21:02:09] "GET /login HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask_socketio/__init__.py", line 46, in __call__
start_response)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/engineio/middleware.py", line 74, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/realp/Desktop/firebaseflask-main/factory/users/views.py", line 63, in login
if session['user']:
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/werkzeug/local.py", line 377, in <lambda>
__getitem__ = lambda x, i: x._get_current_object()[i]
File "/Users/realp/Desktop/firebaseflask-main/env/lib/python3.7/site-packages/flask/sessions.py", line 84, in __getitem__
return super(SecureCookieSession, self).__getitem__(key)
KeyError: 'user'
from flask import render_template, Blueprint, redirect, request, abort, session, jsonify, make_response
from factory import db, auth, database
import random
from factory.models import Users, Cards, Subscription
from flask_login import login_user, current_user, logout_user, login_required
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import date, datetime
from cardvalidator import luhn
import stripe
import json
users = Blueprint('users', __name__)
u/users.route('/register')
def register():
if session['users']:
return redirect('/dashboard')
else:
rand = random.randint(0,100000000)
return render_template('register.html', random=rand)
u/users.route('/insert-user', methods=['POST'])
def reg_user():
if request.method == 'POST':
first_name = str(request.form['first_name'])
last_name = str(request.form['last_name'])
phone_number = str(request.form['phone_number'])
email = str(request.form['email'])
password = str(request.form['password'])
user = auth.create_user_with_email_and_password(email, password)
data = {
"first_name": first_name,
"last_name": last_name,
"phone_number": phone_number,
"free_trial": 1,
"email": email
}
push_user = database.child("users").push(data, user['idToken'])
user_data = auth.get_account_info(user['idToken'])
data_user = {
"email": user_data['users'][0]['email'],
"data": data
}
session['user'] = data_user
return 'success'
u/users.route('/login')
def login():
if session['user']:
return redirect('/dashboard')
else:
rand = random.randint(0,100000000)
return render_template('login.html', random=rand)
u/users.route('/login-user', methods=['POST'])
def login_user_function():
data_user = {}
if request.method == 'POST':
email = str(request.form['email'])
password = str(request.form['password'])
login = auth.sign_in_with_email_and_password(email, password)
# user = auth.refresh(login['refreshToken'])
user_data = database.child("users").get(login['idToken'])
for user in user_data.each():
if user.val()['email'] == email:
data_user = {
"email": email,
"data": user.val()
}
session['user'] = data_user
return 'success'
u/users.route('/logout')
def logout():
session['user'] = {}
return redirect('/login')
# Add new card
u/users.route('/add_card', methods=['POST'])
def new_card():
if request.method == 'POST':
user_id = int(request.form['user_id'])
card_number = str(request.form['card_number'])
expiry = str(request.form['expiry'])
cvc = int(request.form['cvc'])
card_type = str(request.form['card_type'])
card_zip = str(request.form['card_zip'])
check_card = Cards.query.filter_by(card_number=card_number).first()
if check_card is None:
# Insert card
insert_card = Cards(card_number=card_number, expiry=expiry, cvc=cvc, user_id=user_id, card_type=card_type, card_zip=card_zip)
db.session.add(insert_card)
db.session.commit()
return 'success'
else:
return 'existed'
u/users.route('/validate-card', methods=['POST'])
def card_valid():
if request.method == 'POST':
card_number = int(request.form['card_number'])
if luhn.is_valid(card_number):
return 'valid'
else:
return 'fake'
u/users.route('/new-subscription', methods=['POST'])
u/login_required
def new_subscription():
if request.method == 'POST':
card_id = int(request.form['card_id'])
selection = int(request.form['selection'])
email = current_user.email
# # Stripe key
api_key_test = 'sk_test_xxxxx'
public_key_test = 'pk_test_xxxxx'
stripe.api_key = api_key_test
token = stripe.Token.create(
card={
"number": get_card_data.card_number,
"exp_month": int(month),
"exp_year": int(year),
"cvc": get_card_data.cvc,
'address_zip': get_card_data.card_zip
},
)
# return token
customer = stripe.Customer.create(email=email, source=token)
customer_id = customer.id
# # PAYMENT INFORMATION
charge = stripe.Charge.create(
customer = customer_id,
amount = amount,
currency = 'usd',
description = 'Subscription'
)
# Add Subscription
new_subscription = Subscription(
card_id=card_id,
period=selection,
price=(amount/100),
last_payment=datetime.today().strftime('%Y-%m-%d-%H:%M:%S'),
user_id=current_user.id)
db.session.add(new_subscription)
db.session.commit()
return 'success'
If the user is not signed in, there is no key named user in session as you it will be defined when user sign in which raises error. You should check if there is any key user in session.
Rather using in login function.
if session['user']
you should use
if 'user' in session

NOT NULL constraint failed: new__common_farmmodel.user_id

I'm trying to make a part of application for the farmer. I did part with registration, loggin and option "add new farm" for the loggin user, but when I tried to add new farm (filled all fields and click on "POST") it was:
django.db.utils.IntegrityError: NOT NULL constraint failed:
new__common_farmmodel.user_id
I found this NOT NULL constraint failed: user_profile.user_id
and tried redo my FarmModel, by now when tried migrate I get:
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\core\management\base.py", line 364, in execute
output = self.handle(*args, **options)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\core\management\base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\core\management\commands\migrate.py", line 234, in handle
fake_initial=fake_initial,
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\migrations\executor.py", line 245, in apply_migration
state = migration.apply(state, schema_editor)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\migrations\migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\migrations\operations\fields.py", line 249, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\sqlite3\schema.py", line 137, in alter_field
super().alter_field(model, old_field, new_field, strict=strict)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\base\schema.py", line 535, in alter_field
old_db_params, new_db_params, strict)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\sqlite3\schema.py", line 359, in _alter_field
self._remake_table(model, alter_field=(old_field, new_field))
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\sqlite3\schema.py", line 286, in _remake_table
self.quote_name(model._meta.db_table),
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\base\schema.py", line 137, in execute
cursor.execute(sql, params)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\utils.py", line 99, in execute
return super().execute(sql, params)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\filip\.virtualenvs\ToDoBees\lib\site-packages\django\db\backends\sqlite3\base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: new__common_farmmodel.user_id
My actual part of code:
# models.py
FARMER = 'Farmer'
BEEKEEPER = 'Beekeeper'
BUYER = 'Buyer'
USER_TYPE_WITH_NAME_CHOICES = [(FARMER, 'Farmer'), (BEEKEEPER, 'Beekeeper'), (BUYER, 'Buyer')]
class CustomUser(BaseUser):
user = BaseUserManager()
role = models.CharField(choices=USER_TYPE_WITH_NAME_CHOICES, max_length=10, default=BUYER)
telephone = models.CharField(max_length=12)
add_new_farm = models.BooleanField(default=False)
class FarmModel(models.Model):
user = ForeignKey(CustomUser, default=CustomUser, null=None, on_delete=CASCADE)
is_fallen = models.BooleanField(default=False)
it_forest = models.BooleanField(default=False)
farm_location = models.CharField(max_length=250)
since_when_sown = models.DateField()
field_size = models.IntegerField()
additional_description = models.CharField(max_length=1000)
crop_type = models.CharField(max_length=100)
# serializers.py
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(max_length=100, min_length=4, required=True, label='Set your password', write_only=True)
password2 = serializers.CharField(max_length=100, min_length=4, label='Confirm Password', write_only=True)
telephone = serializers.CharField(max_length=12, label='Enter your phone number', required=False)
from .models import USER_TYPE_WITH_NAME_CHOICES
role = serializers.ChoiceField(required=True, choices=USER_TYPE_WITH_NAME_CHOICES)
class Meta:
model = CustomUser
fields = ('email', 'role', 'password', 'password2', 'first_name', 'last_name', 'telephone')
def create(self, validator_data):
user = CustomUser.objects.create()
user.set_password(validator_data['password'])
user.save()
return user
def hash_password(password):
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
pwdhash = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'), salt, 100000)
pwdhash = binascii.hexlify(pwdhash)
return (salt + pwdhash).decode('ascii')
def verify_password(stored_password, provided_password):
salt = stored_password[:64]
stored_password = stored_password[64:]
pwdhash = hashlib.pbkdf2_hmac('sha512', provided_password.encode('utf-8'), salt.encode('ascii'), 100000)
pwdhash = binascii.hexlify(pwdhash).decode('ascii')
return pwdhash == stored_password
def validate(self, attrs):
if attrs.get('password') != attrs.get('password2'):
raise serializers.ValidationError('Those passwords don\'t match.')
return attrs
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = ('add_new_farm',)
class AddFarmSerializer(serializers.ModelSerializer):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta:
model = FarmModel
fields = ('is_fallen', 'it_forest', 'farm_location', 'since_when_sown', 'field_size', 'additional_description', 'crop_type')
def create(self, validated_data):
user = self.context.get('user')
validated_data['user'] = user
return FarmModel.objects.create(**validated_data)
# views.py
User = get_user_model()
class UserRegistration(CreateAPIView):
queryset = User.objects.all()
serializer_class = RegisterSerializer
authentication_classes = ()
permission_classes = ()
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def login_request(request):
return render(request=request, template_name='')
class LoggedUserView(ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def list(self, request, **kwargs):
queryset = self.get_queryset()
serializer = UserSerializer(queryset)
return Response(serializer.data)
class AddFarm(CreateAPIView):
queryset = FarmModel.objects.all()
serializer_class = AddFarmSerializer
def create(self, request, *args, **kwargs):
data = request.data.copy()
data['user'] = request.user
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
user = request.user
serializer = AddFarmSerializer(AddFarm, context={'user': user})
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) ```
You should use boolean field for null. null = None does not make sense.
You can use
null= True or null=False
Here you have to use null=True
because you want null value(by default) supported field
Documentation link here
I suppose that is not problem in model, I think so... Tell me, it is good code in views:
class AddFarm(CreateAPIView):
queryset = FarmModel.objects.all()
serializer_class = AddFarmSerializer
def create(self, request, *args, **kwargs):
data = request.data.copy()
data['user'] = request.user
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
user = request.user
serializer = AddFarmSerializer(AddFarm, context={'user': user})
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
and in serializers:
class AddFarmSerializer(serializers.ModelSerializer):
# permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta:
model = FarmModel
fields = ('is_fallen', 'it_forest', 'farm_location', 'since_when_sown', 'field_size', 'additional_description',
'crop_type')
def create(self, validated_data):
user = self._context.get('user')
validated_data['user'] = user
return FarmModel.objects.create(**validated_data)
?
I can't find any solution :/

Resources