Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Build a Social Network with Flask Broadcasting Stream Views

Gabriel Rivera
PLUS
Gabriel Rivera
Courses Plus Student 11,489 Points

AttributeError: type object 'User' has no attribute 'create_user'

The following is my code for the app.py file:

if name == 'main': models.initialize() try: models.User.create_user( username='GabeRivera', email='gabriel.f.rivera.10@gmail.com', password='turbo13negro', admin=True ) except ValueError: pass app.run(debug=DEBUG, host=HOST, port=PORT)

When i try and run it, I receive this error message: Traceback (most recent call last): File "app.py", line 120, in <module> models.User.create_user( AttributeError: type object 'User' has no attribute 'create_user' (venv)Gabriels-MBP:Greenshare Gabe$

Any help understanding what i am doing wrong, would be greatly appreciated it. Thank you all.

-Gabe

6 Answers

Seth Reece
Seth Reece
32,867 Points

You have a formatting error. In your User class, all thing attributed to that class need to be indented. your class method create_user is not indented under the User class and is not being counted as part of that class. e.g.

class User(UserMixin, Model):
    username = CharField(unique=True)
    email = CharField(unique=True)
    password = CharField(max_length=100)
    joined_at = DateTimeField(default=datetime.datetime.now)
    is_admin = BooleanField(default=False)

# Everything below this line is not being counted as part of the User class

class Meta: 
    database = DATABASE
    order_by = ('-joined_at',)

def get_posts(self):
    return Post.select().where(Post.user == self)

def get_stream(self):
    return Post.select().where(
        (Post.user == self)
    )

@classmethod
def create_user(cls, username, email, password, admin=False):
    try:
        with DATABASE.transaction():
            cls.create(
                username=username,
                email=email,
                password=generate_password_hash(password),
                is_admin=admin)
    except IntegrityError:
        raise ValueError("User already exists")
class User(UserMixin, Model):
    username = CharField(unique=True)
    email = CharField(unique=True)
    password = CharField(max_length=100)
    joined_at = DateTimeField(default=datetime.datetime.now)
    is_admin = BooleanField(default=False)

    # everything below this line is now part of the User  class
    class Meta:
        database = DATABASE
        order_by = ('-joined_at',)

    def get_posts(self):
        return Post.select().where(Post.user == self)

    def get_stream(self):
        return Post.select().where(
            (Post.user == self)
        )

    @classmethod
    def create_user(cls, username, email, password, admin=False):
        try:
            with DATABASE.transaction():
                cls.create(
                    username=username,
                    email=email,
                    password=generate_password_hash(password),
                    is_admin=admin)
        except IntegrityError:
            raise ValueError("User already exists")
Anders Axelsen
Anders Axelsen
3,471 Points

Thank you Seth Reece ! :ocean: I was able to relocate my Relationship(Model) due to reflecting on this tip.

- It made it all work

Cheers!

Seth Reece
Seth Reece
32,867 Points

You probably have a typo in you create_user method in your model. Can you post your code?

Gabriel Rivera
PLUS
Gabriel Rivera
Courses Plus Student 11,489 Points

Thank you for replying Seth, I appreciate the help. Here is my models.py file:

import datetime

from flask.ext.bcrypt import generate_password_hash from flask.ext.login import UserMixin from peewee import *

DATABASE = SqliteDatabase('social.db')

class User(UserMixin, Model): username = CharField(unique=True) email = CharField(unique=True) password = CharField(max_length=100) joined_at = DateTimeField(default=datetime.datetime.now) is_admin = BooleanField(default=False)

class Meta: database = DATABASE order_by = ('-joined_at',)

def get_posts(self): return Post.select().where(Post.user == self)

def get_stream(self): return Post.select().where( (Post.user == self) )

@classmethod def create_user(cls, username, email, password, admin=False): try: with DATABASE.transaction(): cls.create( username=username, email=email, password=generate_password_hash(password), is_admin=admin) except IntegrityError: raise ValueError("User already exists")

class Post(Model): timestamp = DateTimeField(default=datetime.datetime.now) user = ForeignKeyField( rel_model=User, related_name='posts' ) content = TextField()

class Meta: database = DATABASE order_by = ('-timestamp',)

def initialize(): DATABASE.connect() DATABASE.create_tables([User, Post], safe=True) DATABASE.close()

and just incase, here is my app.py file:

from flask import (Flask, g, render_template, flash, redirect, url_for) from flask.ext.bcrypt import check_password_hash from flask.ext.login import (LoginManager, login_user, logout_user, login_required, current_user)

import forms import models

DEBUG = True PORT = 8000 HOST = '0.0.0.0'

app = Flask(name) app.secret_key = 'auoesh.bouoastuh.43,uoausoehuosth3ououea.auoub!'

login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'login'

@login_manager.user_loader def load_user(userid): try: return models.User.get(models.User.id == userid) except models.DoesNotExist: return None

@app.before_request def before_request(): """Connect to the database before each request.""" g.db = models.DATABASE g.db.connect() g.user = current_user

@app.after_request def after_request(response): """Close the database connection after each request.""" g.db.close() return response

@app.route('/register', methods=('GET', 'POST')) def register(): form = forms.RegisterForm() if form.validate_on_submit(): flash("Yay, you registered!", "success") models.User.create_user( username=form.username.data, email=form.email.data, password=form.password.data ) return redirect(url_for('index')) return render_template('register.html', form=form)

@app.route('/login', methods=('GET', 'POST')) def login(): form = forms.LoginForm() if form.validate_on_submit(): try: user = models.User.get(models.User.email == form.email.data) except models.DoesNotExists: flash("Your email or password does not match!", "error") else: if check_password_hash(user.password, form.password.data): login_user(user) flash("You've been logged in!", "success") return redirect(url_for('index')) else: flash("Your email or password does not match!", "error") return render_template('login.html', form=form)

@app.route('/logout') @login_required def logout(): logout_user() flash("You've been logged out! Come back soon!", "success") return rediret(url_for('index'))

@app.route('/new_post', methods=('GET', 'POST')) @login_required def post(): form = forms.PostForm() if form.validate_on_submit(): models.Post.create(user=g.user._get_current_object(), content=form.content.data.strip()) flash("Message Posted! Thank You!", "sucess") return redirect(url_for('index')) return render_template('post.html', form=form)

@app.route('/') def index(): stream = models.Post.select().limit(100) return render_template('stream.html', stream=stream, paginate_by=10)

@app.route('/stream') @app.route('/stream/<username>') def stream(username=None): template = 'stream.html' if username and username != current_user.username: user = models.User.select().where(models.User.username**username).get() stream = user.post.limit(100) else: stream = current_user.get_stream().limit(100) user = current_user if username: template = 'user_stream.html' return render_template(template, stream=stream, user=user)

if name == 'main': models.initialize() try: models.User.create_user( username='GabeRivera', email='gabriel.f.rivera.10@gmail.com', password='turbo13negro', admin=True ) except ValueError: pass app.run(debug=DEBUG, host=HOST, port=PORT)

Thank you again!

Seth Reece
Seth Reece
32,867 Points

Can't duplicate your error. Everything works fine. Perhaps the full message stack trace might be helpful. You could also fork your project in workspace, or push to github. You do have a typo in your logout method 'rediret'. Should be 'redirect'.

Gabriel Rivera
PLUS
Gabriel Rivera
Courses Plus Student 11,489 Points

@Seth Reece I pushed it to my github account, and since i've been getting the error it won't pop up on my browser when i got to "localhost:8000", and i am unable to get the full log. and thank you for catching that typo, i went ahead and changed it. here is the repo, https://github.com/GabeRivera/python_project

Gabriel Rivera
PLUS
Gabriel Rivera
Courses Plus Student 11,489 Points

Seth Reece Thank you so much, I indented it as you showed me and i stopped getting the error. Unfortunately I am still unable to get this working. Now when i try to run "python app.py" i get the following message: File "app.py", line 118, in <module> models.initialize() AttributeError: 'module' object has no attribute 'initialize'

When i checked the app.py file, i noticed that i also made an indentation error.

@app.route('/stream') @app.route('/stream/<username>') def stream(username=None): template = 'stream.html' if username and username != current_user.username: user = models.User.select().where(models.User.username**username).get() stream = user.post.limit(100) else: stream = current_user.get_stream().limit(100) user = current_user if username: template = 'user_stream.html' return render_template(template, stream=stream, user=user)

if name == 'main': models.initialize() try: models.User.create_user( username='GabeRivera', email='gabriel.f.rivera.10@gmail.com', password='turbo13negro', admin=True ) except ValueError: pass app.run(debug=DEBUG, host=HOST, port=PORT)

So i indented the if_name=='main_': section. and now it looks like so:

@app.route('/stream') @app.route('/stream/<username>') def stream(username=None): template = 'stream.html' if username and username != current_user.username: user = models.User.select().where(models.User.username**username).get() stream = user.post.limit(100) else: stream = current_user.get_stream().limit(100) user = current_user if username: template = 'user_stream.html' return render_template(template, stream=stream, user=user)

if __name__ == '__main__':
    models.initialize()
    try:
        models.User.create_user(
            username='GabeRivera',
            email='gabriel.f.rivera.10@gmail.com',
            password='turbo13negro',
            admin=True
        )
    except ValueError:
        pass
    app.run(debug=DEBUG, host=HOST, port=PORT)

but now anytime i try to run it on the console. "python app.py", i does nothing and just deletes what i typed. Now Im really lost haha, thank you for the help.

Seth Reece
Seth Reece
32,867 Points

That part should not be indented. Make sure in your model that your meta class is indented under the Post class, but that initialize is not indented.