2017-05-16 8 views
0

AddSongFormの1つのフィールドにカスタムバリデーターを作成しようとしています。インラインバリデーターを使用し、私のSongsクラスの2つのメソッドを使用します。私はコードを実行しようとしたとき、私は戻って、次のトレースを取得:これは私が使用したクラスのメソッドフォームを検証するためにフォームデータをメソッドに渡すことができません

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 

私は

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 

されており、ここにありますPythonでかなり新しくなりました。これはOOコードを書く初めてのことなので、何が起こっているのか分かりません。この問題以外にも、コードについてのフィードバックや、ある意味で改善の余地があるのであれば、私は満足しています。

答えて

1

私はこれらが歌のメソッドであると確信していません。彼らはソングのクラスとは関係がありません。

ただし、それらをメソッドとして保持したいがクラスから呼び出す場合は、インスタンスメソッドではなくクラスメソッドである必要があります。

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

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

別のメソッドの中でそれらを使用して、Songオブジェクトに新しい属性を追加します。その理由は、それらをSongの中に入れる理由です。私はDRYの原則を守って検証をするためにそれらを使うこともできます。 あなたの意見では、それらを正規の関数で変換し、必要に応じてコード内で呼び出す必要がありますか? – illichosky

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 
関連する問題