Postępuję Ta samouczek do zbudowania systemu uwierzytelniania opartego na bazie JWT.

App.py:

from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'd0cad49580952003e6ae01499c7bb190a4b4f9a5babd866f47064707f7b78506'

api = Api(app)
db = SQLAlchemy(app)


@app.before_first_request
def create_tables():
    db.create_all()


import resources, models

api.add_resource(resources.UserRegistration, '/registration')


if __name__ == '__main__':
    app.run()

Models.py:

from app import db


class UserModel(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(150), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)

    def __init__(self, name, password, email):
        self.name = name
        self.password = password
        self.email = email

    @classmethod
    def find_by_username(cls, username):
        return cls.query.filter_by(username=username).first()

    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

Zasoby.py:

from flask_restful import Resource, reqparse
from models import UserModel


class UserRegistration(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name', help='This field cannot be blank', required=True)
        parser.add_argument('email', help='This field cannot be blank', required=True)
        parser.add_argument('password', help='This field cannot be blank', required=True)

        data = parser.parse_args()

        if UserModel.find_by_username(data['name']):
            return {'message': 'User {} already exists'.format(data['name'])}

        new_user = UserModel(
            name=data['name'],
            password=data['password'],
            email=data['email']
        )
        try:
            new_user.save_to_db()
            return {
                'status': 'User {} was created'.format(data['username'])}

        except:
            return {'message': 'Something went wrong'}, 500

Po uruchomieniu app.py, otrzymuję następujący błąd:

Traceback (most recent call last):
  File "G:\python\PycharmProjects\vumonic\app.py", line 19, in <module>
    import resources, models
  File "G:\python\PycharmProjects\vumonic\resources.py", line 2, in <module>
    from models import UserModel
  File "G:\python\PycharmProjects\vumonic\models.py", line 1, in <module>
    from app import db
  File "G:\python\PycharmProjects\vumonic\app.py", line 21, in <module>
    api.add_resource(resources.UserRegistration, '/registration')
AttributeError: module 'resources' has no attribute 'UserRegistration'

Ten błąd znika, gdy usuwam from models import UserModel z zasobów.py.

Nie mogę wymyślić powodu błędu.

Używam Flask == 1.1.2, Flask-Sqlalchemy == 2.4.4 i Flask-Restful == 0.3.8

Po raz pierwszy rozwijam interfejs API, więc wszelka pomoc byłaby doceniana.

0
Ayush Agarwalla 28 lipiec 2020, 14:13

1 odpowiedź

Najlepsza odpowiedź

W obliczu okrągłego problemu importu.

Gdy Python importuje moduł, sprawdza rejestr modułu, aby sprawdzić, czy moduł był już importowany. Jeśli moduł był już zarejestrowany, Python używa tego istniejącego obiektu z pamięci podręcznej. Rejestr modułu jest tabelą modułów, które zostały zainicjowane i indeksowane przez nazwę modułu. Dostęp do tej tabeli można uzyskać za pomocą sys.modules.

Jeśli nie został zarejestrowany, Python znajduje moduł, inicjuje go w razie potrzeby i wykonuje go w przestrzeni nazw nowego modułu.

Aby dowiedzieć się więcej o imporcie kołowym, możesz przeczytać artykuł:

https://stackabuse.com/python-circular-imports/

https://www.stefaanlippens.net/circred-imports-type-hints-Python.html.

Ten tutorial Miguel Grinberg jest życiem Zbawicielem życia https://www.youtube.com/watch?v=nh- 8OLHUYDC & AMP; T = 3205S

1
Tasnuva 28 lipiec 2020, 15:28