无法将表单数据传递给方法以验证表单

时间:2017-05-16 11:56:58

标签: python flask wtforms

我正在尝试为AddSongForm中的一个字段创建自定义验证程序。我使用了内联验证器,它使用了我的Songs类中的两个方法。当我尝试运行代码时,我得到以下追溯:

form = AddSongForm()
[2017-05-16 13:44:11,547] ERROR in app: Exception on /addsong [POST]
Traceback (most recent call last):
File "C:\Python36-32\lib\site-packages\flask\app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python36-32\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python36-32\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python36-32\lib\site-packages\flask\_compat.py", line 33, in reraise
raise value
File "C:\Python36-32\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python36-32\lib\site-packages\flask\app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Python36-32\lib\site-packages\flask_login\utils.py", line 228, in decorated_view
return func(*args, **kwargs)
File "C:/Users/Pellissari/Desktop/files/projects/Musical 9gag/view.py", line 40, in addsong
if form.validate_on_submit():
File "C:\Python36-32\lib\site-packages\flask_wtf\form.py", line 101, in validate_on_submit
return self.is_submitted() and self.validate()
File "C:\Python36-32\lib\site-packages\wtforms\form.py", line 310, in validate
return super(Form, self).validate(extra)
File "C:\Python36-32\lib\site-packages\wtforms\form.py", line 152, in validate
if not field.validate(self, extra):
File "C:\Python36-32\lib\site-packages\wtforms\fields\core.py", line 204, in validate
stop_validation = self._run_validation_chain(form, chain)
File "C:\Python36-32\lib\site-packages\wtforms\fields\core.py", line 224, in _run_validation_chain
validator(form, self)
File "C:\Users\Pellissari\Desktop\files\projects\app\forms.py", line 20, in validate_song_link
if Songs.get_provider(url) in valid_providers:
TypeError: get_provider() missing 1 required positional argument: 'url'
127.0.0.1 - - [16/May/2017 13:44:11] "POST /addsong HTTP/1.1" 500 -

这是我的表单类

class AddSongForm(Form):
    song_title = StringField('song_title', validators=[DataRequired()])
    song_artist = StringField('song_artist', validators=[DataRequired()])
    song_genre = StringField('song_genre')
    song_link = StringField('song_link', validators=[DataRequired()])

    def validate_song_link(form, song_link):
    valid_providers = ['youtube.com', 'www.youtube.com', 'soundcloud.com', 'www.soundcloud.com']
    url = song_link.data
    if Songs.get_provider(url) in valid_providers:
        if Songs.get_embed_code(url) is not False:
            return True
        else:
            print("couldn't get your content")
            return False
    else:
        print("unsupported provider")
        return False

这是我使用方法

的类
class Songs(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    title = db.Column(db.String(50))
    artist = db.Column(db.String(30))
    genre = db.Column(db.String(40))
    author = db.Column(db.String(40))
    timestamp = db.Column(db.DateTime)
    likes_num = db.Column(db.Integer)
    song_link = db.Column(db.String(120))

    def get_provider(self, url):
        return urllib.parse.urlsplit(url)[1]

    def get_embed_code(self, url):
        code = None
        vars = {'url': url, 'format': 'json', 'iframe': 'true', 'maxwidth': '450', 'show_comments': 'false'}
        provider = self.get_provider(url)
        endpoint = "http://"+provider+"/oembed?"
        source = endpoint+urllib.parse.urlencode(vars)
        try:
            request = urlopen(source)
            code = json.load(request)['html']
            return code
        except:
            print("impossible to get your content. Check the link") 
            return False

我是Python的新手,这是我第一次编写OO代码,所以我不知道这里会发生什么。除了这个问题之外,如果你能给我一些关于代码的反馈,并且在某种意义上还有改进的余地,我会很高兴。

2 个答案:

答案 0 :(得分:1)

我不相信这些应该是歌曲上的方法。他们没有提及与Song课程有关的事情。

但是如果你想把它们作为方法,但仍想从类中调用它们,它们需要是classmethods,而不是实例方法。

@classmethod
def get_provider(cls, url):
    return urllib.parse.urlsplit(url)[1]

@classmethod
def get_embed_code(cls, url):
    ...
    provider = cls.get_provider(url)

答案 1 :(得分:1)

首先纠正方法validate_song_link的缩进。它应该是这样的:

def validate_song_link(form, song_link):
    valid_providers = ['youtube.com', 'www.youtube.com', 'soundcloud.com', 'www.soundcloud.com']
    url = song_link.data
    if Songs.get_provider(url) in valid_providers:
        if Songs.get_embed_code(url) is not False:
            return True
        else:
            print("couldn't get your content")
            return False
    else:
        print("unsupported provider")
        return False

要解决您的问题,您可以尝试将get_provider方法更改为类似的类方法:

@classmethod
def get_provider(cls, url):
    return urllib.parse.urlsplit(url)[1]

然后你可以这样说:

songs = Songs()

if Songs.get_provider(songs, url) in valid_providers:
    if Songs.get_embed_code(url) is not False:
        return True