2017-12-20 21 views
2

私は、次の機能を持っている:文字列を引数名として渡すにはどうすればよいですか?

def create_act(user, verb, fk_name=None, fk_value=None): 
    fk = getattr(Action, fk_name) 
    action = Action(user=user, verb=verb, fk=fk_value) 
    action.save() 

アクションクラスです。クラスには複数の属性があり、最初にどの属性が値を取得するかわかりません。

属性名は動的です。

kwarg fkをクラスアクションの実際の属性にします。 FKは口座または会社とすることができます。

class Action(models.Model): 

account = models.ForeignKey(Account, blank=True, null=True, related_name='activity', on_delete=models.CASCADE) 
company = models.ForeignKey(Company, blank=True, null=True, related_name='activity', on_delete=models.CASCADE) 

私は、フォーラムにいくつかの答えが、私には何も関連を発見した、またはパイソンインチ 他のサイトでevalを使用する提案がありましたが、evalは安全ではありません。

+0

役立ちリンクです:https://stackoverflow.com/questions/3394835/args-and-kwargs –

+0

あなたには、いくつかの例を与えた場合、それが参考になる*が値属性は、辞書アンパックを使用してそれに沿って渡します*とエミュレートしたい呼び出しの種類の例。あなたは 'Action(..、fk = ...)'の 'fk'は' fk'変数に基づく可変の値でなければならないと言っていますか? 'アクション(...、foo = fk_value)'? – deceze

+0

@decezeもっと情報が追加されました、djangoですインスタンスを作成し、fkは外部キーです – user3541631

答えて

5

**で開梱してdictを使用してください。 - fk_nameForeignKey - fkの名前である場合は、文字列ではなく、ForwardManyToOneDescriptorとなります。あなたはおそらくまだfk_nameという名前の属性を設定したいと思います:

action = Action(user=user, verb=verb, **{fk_name: fk_value}) 
+1

ディクテーションの解凍は正しかったですが、確かに 'fk' *は文字列ではありません。 –

+0

@DanielRoseman fk_nameは初期関数の引数です。文字列です.getattrを使わずに直接使用できますか? – user3541631

+2

@DanielRoseman動的キーワード割り当てを達成するためにどのフォームを使用できるかはまだ分かります。 OPの問題はこれに翻訳可能でなければなりません。 – Arne

1

アイデアが動的にそれを行うために、クラス作成に属性名と値のペアを渡すことで、名前/値を使用して辞書を作成しますここ

def create_act(user, verb, name, value): 
    attrs = {name: value} 
    action = Action(user=user, verb=verb, **attrs) 
    action.save() 
    return action 
関連する問題