AttributeError: у объекта 'function' нет атрибута 'place_id' - PullRequest
0 голосов
/ 29 июня 2018

Я пытался выполнить функцию «пользователи, следующие за школами» на нашем веб-сайте, и я создал таблицу взаимосвязей (названную «follow») следующим образом:

class Follow(db.Model):
    __tablename__ = 'follow'
    follower_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)  
    followed_id = db.Column(db.String(50), 
    db.ForeignKey('school.place_id'),primary_key=True)  
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)

и соответствующие атрибуты модели пользователя и школы:

 class User(UserMixin, db.Model):
   __tablename__ = 'user'
   id = db.Column(db.Integer, primary_key=True)
   followed = db.relationship('Follow',
                                foreign_keys=[Follow.follower_id],
                                backref=db.backref('follower', lazy='joined'),
                                lazy='dynamic',cascade='all,delete-orphan')
 class School(db.Model):
    _tablename_ = 'school'
    place_id = db.Column(db.String(50), primary_key=True)
    followers = db.relationship('Follow',  
                           foreign_keys=[Follow.followed_id],
                           backref=db.backref('followed,lazy=joined'),  # corresponding followed_id
                           lazy='dynamic',
                           cascade='all, delete-orphan')

Кроме того, я написал три метода, которые относятся к следующему поведению в модели пользователя

def follow(self, school):                          
        if not self.is_following(school):
            f = Follow(follower=self, followed=school)    
            db.session.add(f)                           
            db.session.commit()


def unfollow(self, school):                       
        f = self.followed.filter_by(followed_id=school.place_id).first()       
        if f is not None:
            db.session.delete(f)
            db.session.commit()


def is_following(self,school):
        return self.followed.filter_by(followed_id=school.place_id).first() is not None

и я также написал следующее в моем main / views.py

@main.route('/follow/<official_school_name>')
@login_required
# @permission_required(Permission.USER_LIKE)
def follow(official_school_name):
    school = School.query.filter_by(official_school_name=official_school_name).first()
    if school is None:
        flash('Invalid school name.')
        return redirect(url_for('.index'))
    if current_user.is_following(school):
        flash('You have already followed this school.')
        return redirect(url_for('.school', official_school_name=school.official_school_name, roll_number=school.roll_number))
    current_user.follow(user)
    flash('You are not following %s.' % official_school_name)
    return redirect(url_for('.school', official_school_name=school.official_school_name, roll_number=school.roll_number))

Наконец, я только что сделал неформальную кнопку для проверки следующей функции.

 <a href="{{ url_for('.follow', official_school_name=school.official_school_name, roll_number=school.roll_number) }}"
        class = "btn btn-primary">Follow</a>

Однако, когда я нажимаю кнопку Follow, появляется сообщение об ошибке:

File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 2309, in __call__
Open an interactive python shell in this framereturn self.wsgi_app(environ, start_response)
File "C:\Users\kjhk\venv\lib\site-packages\werkzeug\contrib\fixers.py", line 152, in __call__
return self.app(environ, start_response)
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\kjhk\venv\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\kjhk\venv\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "E:\Project0619\ProjectTest\Code\app\main\views.py", line 197, in follow
current_user.follow(user)
File "E:\Project0619\ProjectTest\Code\app\models\User.py", line 99, in follow
if not self.is_following(school):
File "E:\Project0619\ProjectTest\Code\app\models\User.py", line 113, in is_following
return self.followed.filter_by(followed_id=school.place_id).first() is not None
AttributeError: 'function' object has no attribute 'place_id'

Я попытался изменить функцию is_following следующим образом:

 def is_following(self,school):
            return self.followed.filter_by(followed_id=school.id).first() is not None

затем появилась другая ошибка:

 File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\kjhk\venv\lib\site-packages\werkzeug\contrib\fixers.py", line 152, in __call__
    return self.app(environ, start_response)
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\kjhk\venv\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\kjhk\venv\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\kjhk\venv\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\kjhk\venv\lib\site-packages\flask_login\utils.py", line 261, in decorated_view
    return func(*args, **kwargs)
  File "E:\Project0619\ProjectTest\Code\app\main\views.py", line 194, in follow
    if current_user.is_following(school):
  File "E:\Project0619\ProjectTest\Code\app\models\User.py", line 113, in is_following
    return self.followed.filter_by(followed_id=school.id).first() is not None
AttributeError: 'School' object has no attribute 'id'

Это доказывает, что второй argus (School.id) может относиться к модели «Школа», но любой может помочь мне ответить, почему появилась первая ошибка? Большое спасибо!

1 Ответ

0 голосов
/ 29 июня 2018

Эта ошибка: AttributeError: 'School' object has no attribute 'id' не очень доказывает вашу другую проблему. Внимательный взгляд на каждый стек вызовов говорит нам больше о том, что происходит:

Первый вызов использует if not self.is_following(school) в качестве точки входа, в то время как второй вызов использует if current_user.is_following(school). Я вижу это по сообщениям, которые вы опубликовали.

Во втором вы определяете школу как:

school = School.query.filter_by(official_school_name=official_school_name).first()

И в последнем случае school фактически является экземпляром класса School.

Однако в первом примере школьный аргумент передается как user:

current_user.follow(user)<-----

... и user явно определены в вашем коде как тип function. Вы можете проверить это, напечатав или вернув type(user).

Передайте school на первый звонок, и это должно остановить проблему AttributeError: 'function' object has no attribute 'place_id'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...