こんにちは、Habr!
最近python / djangoでサイトを開発し、Vkontakte APIを使用する機能が必要でした。 すなわち:
•サイトからVkontakteのページ、および選択したグループ(管理者を含む)への記事の投稿。
•文書や写真を記録に添付する機能。
•更新されたスクリプトを使用してグループとエントリのリストを取得し、すべてをdjango管理パネルにロードします。
実際、管理者にとって、この機能は管理パネルで管理されます。
この機能の実装を段階的に説明します。
最初の段階では、管理者はVkontakteでアプリケーションを作成し、APIを操作するためのトークンを取得する必要があります。 トークンを取得するには、VKAppAuthモジュールを使用します(GitHubへのリンク 、モジュールの使用例があります)。
受信用の設定を別のファイルに保存し、models.pyに接続します。 models.pyで、Vkontakteのフィールドを記事モデルに追加します。
photo_vk = models.ImageField(upload_to=photo_vk_path, verbose_name=u' ', max_length = 1000, blank=True) file_vk = models.FileField(upload_to=files_vk_path, verbose_name=u' ', max_length = 1000, blank=True) wall_user_vk = models.BooleanField(verbose_name=u' ', default=False) group_vk = models.ManyToManyField(Vk_groups, verbose_name=u' ', blank=True) group_stat = models.BooleanField(verbose_name=u' ', default=False)
group_vkフィールドには、Vk_groupsテーブルのすべてのVkontakteグループが表示されます。 models.pyのVk_groupsクラスコード:
class Vk_groups(models.Model): title = models.CharField(max_length=1000, verbose_name=u' ') gid = models.CharField(max_length=1000, verbose_name=u'ID ') is_closed = models.BooleanField(verbose_name=u' ', default=False) is_admin = models.BooleanField(verbose_name=u' ', default=False) def __str__(self): return self.title.encode('utf8') class Meta: verbose_name = " " verbose_name_plural = " "
Vkontakteレコード用のモデルも作成されています。 サーバー上で自動的に更新されるスクリプトを使用して読み込まれます。したがって、管理パネルには、管理者のページと、彼がメンバーになっているグループからの現在のエントリがあります。
モデルフィールド:
class Vk_posts(models.Model): group = models.CharField(max_length=1000, verbose_name=u'/', blank=True) text = HTMLField(verbose_name=u' ', blank=True) date = models.DateTimeField(verbose_name=u' ', blank=True)
記事モデルでは、save()メソッドを再定義し、記事を保存するときにVkontakte APIにアクセスし、対応するチェックボックスがオンになっている場合にレコードがVkontakteに送信されるようにしました。
def save(self, *args, **kwargs): use_vk(self) model = super(Page, self).save(*args, **kwargs)
保存する前に、use_vk関数が呼び出され、APIが呼び出されます。
# photo_vk_path = 'photo_vk' files_vk_path = 'files_vk' def use_vk(self): # msg = self.title + '\n' + self.text msg = re.sub('<.*?>','',msg) # , post_vk = 0 # groups = [g for g in self.group_vk.all()] if len(groups) or self.wall_user_vk: post_vk = 1 if post_vk: attachments = [] # if self.photo_vk: server = vk.photos.getWallUploadServer(uid = my_id) path = MEDIA_ROOT + photo_vk_path + '/' + re.split('/', self.photo_vk.url)[-1] r = requests.post(server['upload_url'], files={'photo': open(path,"rb")}) params = {'server': r.json()['server'], 'photo': r.json()['photo'], 'hash': r.json()['hash']} wallphoto = vk.photos.saveWallPhoto(**params) attachments.append(wallphoto[0]['id']) # if self.file_vk: server = vk.docs.getWallUploadServer() path = MEDIA_ROOT + files_vk_path + '/' + re.split('/', self.file_vk.url)[-1] r = requests.post(server['upload_url'], files={'file': open(path,"rb")}) params = {'file': r.json()['file']} doc = vk.docs.save(**params) attachments.append('doc' + str(my_id) + '_' + str(doc[0]['did'])) params = {'attachments': ','.join(attachments), 'message': msg} # if self.wall_user_vk: params['owner_id'] = my_id vk.wall.post(**params) # if len(groups): if self.group_stat: params['from_group'] = 1 for g in groups: params['owner_id'] = g.gid vk.wall.post(**params)
写真とドキュメントのローダーは、そのurlメソッドを呼び出すことでフォルダー内のファイルへの誤ったパスを提供したことに注意する必要があります(所有していることを除外しません)。
写真またはドキュメントを記録にアップロードする手順の詳細:
a)写真またはドキュメントをアップロードできるVkontakteサーバーのアドレスを取得する要求を送信します。
b)Vkontakteサーバーのアドレスの取得。
c)文書または写真のアップロードを伴うサーバーアドレスへのポストリクエストの形成。
d)アップロードが成功すると、アップロードされたドキュメントまたは写真の識別子を含む応答を受信します。
e)写真またはドキュメントの識別子を含む、Vkontakteに投稿するための属性のリストの形成。
写真/ドキュメントを添付した後、最終的なAPIメソッドvk.wall.post(** params)が使用され、管理者/グループのウォールレコードにレコードが送信されます。
グループのリストを取得し、グループおよび管理者のウォールから新しいエントリを保存するには、指定された時間にサーバー上で自動的に更新されるスクリプトが使用されます。 このスクリプトは、django設定を受け取り、必要なモデルとトークン受信ファイルをインポートし、APIを介して管理者グループ、ウォールからのレコード、グループからのレコードを受け取り、データベーステーブルを更新します。
import sys import time sys.path = ['C:/site/umc/'] + sys.path from django.core.management import setup_environ import settings setup_environ(settings) from www.models import Vk_groups, Vk_posts from umc.vk_response import * count_posts = 15 def get_posts(owner_id, g_name): """ Vk_posts""" params = {'owner_id': owner_id, 'count': count_posts} answer = vk.wall.get(**params) for i in range(count_posts): params = { 'group': g_name, 'text': answer[i+1]['text'], 'date': time.strftime("%Y-%m-%d %H:%M:%S+06:00", time.localtime(answer[i+1]['date'])) } try: Vk_posts.objects.get_or_create(**params) except: params['text'] = u' ' Vk_posts.objects.get_or_create(**params) # Vk_groups params = {'owner_id': my_id, 'extended': 1, 'filter': 'events, groups, admin'} answer = vk.groups.get(**params) for i in range(answer[0]): Vk_groups.objects.get_or_create(title = answer[i+1]['name'], gid = '-' + str(answer[i+1]['gid']), is_admin = answer[i+1]['is_admin'], is_closed = answer[i+1]['is_closed']) # Vk_posts groups = Vk_groups.objects.all() for g in groups: get_posts(g.gid, g.title) # Vk_posts user = vk.users.get(uid = my_id) get_posts(my_id, user[0]['first_name']+ ' ' + user[0]['last_name'])
実際、管理パネルから壁または任意のグループ(アクセス権によりグループウォールにメモを配置できる場合)にメモを送信して、作業を確認できます。
記事がお役に立てば幸いです。
プロジェクトへのリンク: github.com/julia-bikova/DjangoVkPosting
Djangoでの作業をお楽しみください!