Django エラーModuleNotFoundError: No module named 'virtualenvwrapper'

こんなエラーがでた。 環境 MAC OS 10.15.2 python 3.5 Django 2.2

ModuleNotFoundError: No module named 'virtualenvwrapper'

Djangoで開発中の、デバッグ中に発生する

virtualenvwrapperとは

公式サイト virtualenvwrapper.readthedocs.io

virtualenvwrapper の特徴

すべての virtualenv 環境を一元管理できる
便利な各種コマンド
環境の切り替えがコマンドひとつでタブによるコマンド補完
カスタマイズ可能なフック
拡張機能も自由に開発可

便利な開発環境を提供してくれます。 これは従来

pip install virtualenvwrapper

でインストールできていた。

.bash_profile

//pyenv関係
export PATH="$HOME/.pyenv/shims:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

//システム標準のpython
export PATH=$PATH:/Users/imac2/Library/Python/3.7/bin
alias python="python3"

export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3

brew では、pyenv がインストールされている

$ brew list
autoconf        libimobiledevice    openssl@1.1
automake        libplist        pkg-config
aws-elasticbeanstalk    libtasn1        pyenv //ここにある
carthage        libtool         python //pythonも

pyenvとは

pythonのバージョンを同一PC内で使い分けることが可能。

pyenvで利用される shimコマンドとは

shimコマンドは、 $HOME/.pyenv/shims/ に配置されるコマンド群

  • 環境のpythonのバージョンを調べて、そのバージョンを利用する
  • .python-version ファイルがあればそのpythonのバージョンを利用する

これにより、環境を構築したフォルダに .python-version があれば、そのバージョンを開発に利用できる

virtualenvの構成

virtualenvのコマンドで、任意のディレクトリにPython の実行環境を作成できる pythonコマンドは、自身の親ディレクトリにある include,libディレクトリを参照する。 現在これを利用していた。 f:id:happy_teeth_ago:20200103104601p:plain

参考にさせていただきました。

stackoverflow.com

この記事によると

最近のHomebrewの更新後も同じ問題が発生しました。

過去には、ほとんどの人がpip install virtualenvwrapperをシステムサイトパッケージに実行していましたが、それは機能していました。

Homebrewは、

1)システムpythonをシャドウイングしなくなり、

2)pipをpip2 / pip3にシンボリックリンクしなくなった.

上記理由により、このワークフローが中断されました。

ほとんどのユーザーは、pipが見つからないときにこれを認識し、pip2 / pip3を使用しようとします。 しかし、virtualenvwrapperはpython2 / python3ではなくpython2 / python3にインストールされるため、pip2 / pip3を使用すると問題が発生します。 そのため、virtualenvwrapperを実行してpythonを呼び出すと、システムpythonのサイトパッケージでvirtualenvwrapper / virtualenv pythonパッケージが見つかりません。のエラーが発生する。

VIRTUALENVWRAPPER_PYTHONを明示的に設定することは最もクリーンな修正である。 ふむふむ

仮想環境を利用するときのactivateは何をしているのか?

//activateより
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
どこにpipでインストールされているのか pip show コマンドで調べる
//これでpipのインストール場所を調査できる
$ pip show virtualenvwrapper

Name: virtualenvwrapper
Version: 4.8.4
Summary: Enhancements to virtualenv
Home-page: https://virtualenvwrapper.readthedocs.io/
Author: Doug Hellmann
Author-email: doug@doughellmann.com
License: MIT

//これはおかしい
Location: /Users/imac2/.pyenv/versions/3.5.2/lib/python3.5/site-packages
Requires: virtualenv, virtualenv-clone, stevedore

.pyenvに入っている!!

現在の開発の仮想環境にインストールされていない。 解決方法は2つ

1-今の環境を指定してVIRTUALENVWRAPPERをpipインストールする。

-t オプションでインストール可能

2-VIRTUALENVWRAPPER_PYTHONのpathを設定してあげる

.bashrc

bashrcはbashを起動するたびに毎回呼ばれる。 シェル関数を定義したりする。 .bash_profileは起動時1回しか呼ばれない。

export WORKON_HOME=$HOME/.virtualenvs
source /Users/hideyasuimac2/.pyenv/shims/virtualenv/virtualenvwrapper.sh

参考にさせていただきました。

qiita.com

Django エラー return Database.Cursor.execute(self, query, params) django.db.utils.OperationalError: no such table:

エラーメッセージ

  return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: xxxxxx.app

マイグレーションをしていないだけ

解決

$ python manage.py makemigrations

$ python manage.py migrate

$ python manage.py makemigrations
Migrations for 'xxxxapp':
  xxxxapp/migrations/0001_initial.py
    - Create model Restaurant


$ python manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, xxxxxapp, oauth2_provider, sessions, social_django
Running migrations:
  Applying xxxxxapp.0001_initial... OK

Djangoのバージョンの確認方法

pythonとターミナルで入力するとコマンドラインを実行できる >>>が表示される

$ python

Python 3.5.2 (default, Dec 20 2019, 17:56:26) 
[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

ここで

import jango

を入力 そして
get_version()関数を実行する

django.get_version()

>>> import django
>>> django.get_version()
'1.10'
>>> 

Djangoのバージョン1.10でした。

AttributeError: module Django.contrib.auth.views has no attribute

AttributeErrorが出たときの対応

url.py

from django.conf.urls import url
from . import views
from django.contrib.auth import views as auth_views

urlpatterns = [

    url(r'^$', views.home),

//ここが間違い
    url(r'^login/$', auth_views.login, {'template_name': 'useraccounts/login.html'}, name='login'),
    url(r'^logout/$', auth_views.logout, {'template_name': 'useraccounts/logout.html'}, name='logout'),
    url(r'^registration/$', auth_views.registration, {'template_name': 'useraccounts/registration.html'}, name='registration'),

]

解決法

from django.contrib.auth.views import LoginView

そして該当箇所を変更

  url(r'^login/$', LoginView.as_view(), {'template_name': 'useraccounts/login.html'}, name='login'),

このas_view()はなにをしているのかを説明

関数定義

github.com

ここでは、requestを受けとり、dispachメソッドを返却している。

  def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            self.setup(request, *args, **kwargs)
            if not hasattr(self, 'request'):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            return self.dispatch(request, *args, **kwargs)

dispachメソッドは、リクエストメソッドを判定して、実装されていたら、それを実行する。

なので関数を返しているだけ。 そもそもとしてなぜこんなことをする必要があるかというと。 DjangoのViewは下記の3つの条件を満たさないといけないらしい。

  • requestオブジェクトを(第一引数として)受け取る
  • callableである
  • responseオブジェクトを返す

再利用可能なように、クラスベースのビューに変更になったようです。

これを満足させるために、as_view()を使っている。

参考にさせていただきました。

qiita.com

WordPressマルチサイト機能による多言語対応 xserver

まずサーバーパネルでSSLの設定をする
xserverはサブフォルダ型

xxxx/ja

xxxx/en

のようにサブフォルダのように表示される

バックアップを取っておくこと

公式サイトはこちら

wpdocs.osdn.jp

SSLの場合最初にWordPressアドレスをhttpsに変更しておく。

マルチサイトにすると変更できなくなるため f:id:happy_teeth_ago:20191226172153p:plain

wp-config.phpの設定を変更

下記を追加

define ('WP_ALLOW_MULTISITE', true);

f:id:happy_teeth_ago:20191226162118p:plain

管理画面をリロードすると、

ツール>サイトネットワークの設置

というのが表示されるようになる。

f:id:happy_teeth_ago:20191226172255p:plain

Xserverはサブディレクトリ型を選択 f:id:happy_teeth_ago:20191226164107p:plain

wp-config.php に追加

define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'tokutoku555.club');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

.htaccessへ追加

既存のWordPressの設定を置き換える(以前のものは削除すると言うこと)

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

これを書き換えると、再度ログインする。

サイトネットワーク管理が追加されている。 これがadmin権限、 今後こちらでプラグインの追加やテーマの追加をする。

サイトの管理で新規言語サイトを追加できる

f:id:happy_teeth_ago:20191226164339p:plain

新規サイトの追加の記入例 f:id:happy_teeth_ago:20191226164541p:plain

swift Alamofire login 忘備録

Alamofireはswiftyjsonと一緒に使うことが多い

Alamofireは、セッション等通信に利用する。

swiftyjsonは 受け取ったjsonレスポンスをswiftに取り込むためと考える。

理由は、jsonのファイルには、配列やオブジェクトが混じっていることが多いが、それをきれいに取り出してくれる仕組みがある。

ここのイニシャライザがわかりやすい。 github.com

SwiftyJSONの使い方

import SwiftyJSON

//こんな感じで利用
let json = JSON(data: dataFromNetworking)

let json = JSON(jsonObject)

Alamofire(アラモファイアー)のリクエストはこちら

github.com

Alamofireのリクエスト例

func request<Parameters: Encodable>(_ convertible: URLConvertible,
                                         method: HTTPMethod = .get,
                                         parameters: Parameters? = nil,
                                         encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default,
                                         headers: HTTPHeaders? = nil,
                                         interceptor: RequestInterceptor? = nil) -> DataRequest

で実際のコード

//ログインを実装するよ
//@escapingは非同期や、他で参照される可能性があるということ。ここでは非同期のため。
   func login(userType: String, completionHandler: @escaping (NSError?) -> Void) {
        
     //パラメータ requestを生成するため
        let path = "api/social/convert-token/"
        let url = baseURL!.appendingPathComponent(path)
        let params: [String: Any] = [
            "grant_type": "convert_token",
            "client_id": CLIENT_ID,
            "client_secret": CLIENT_SECRET,
            "backend": "facebook",
            "token": AccessToken.current?.tokenString,
            "user_type": userType
        ]
        
//ここはリクエストなので、Alamofireを利用
       let request = Alamofire.request(url!,
                          method: .post,
                          parameters: params,

//ここはAlamofireのURLEncoding()を使うよ
                          encoding: URLEncoding(),
                          headers: nil)

        //投げたリクエストに対してのレスポンス処理 swiftyjson
        request.responseJSON { (response) in

//responseは .success と .failureが返却されるので、切り分ける
            switch response.result {

//レスポンスが帰ってきたときの処理
            case .success(let value):
                
//ここで上記のイニシャライザを利用
                let jsonData = JSON(value)
       
//.string!だけで string型にしてくれるだけでなく、nilのときは、そのまま空白を返却してくれる。落ちないので良い     
                self.accessToken = jsonData["access_token"].string!
                self.refreshToken = jsonData["refresh_token"].string!

//セッションが切れるときは、レスポンスのexpires_inに入っているよ
                self.expired = Date().addingTimeInterval(TimeInterval(jsonData["expires_in"].int!))
                completionHandler(nil)
                break

//だめだったときは、エラーをはく。チェックのため。
            case .failure(let error):
                completionHandler(error as NSError)
                break
                
            }
        }
      

objective-c 読み方

Objectiv-C 基本事項

@interfaceがheader部という。変数や関数名が記載されている。

@implementationが実装部で、実際の関数の定義が記載されている

@はコンパイラへの命令を意味します。

header部

@interface UIViewController(SWRevealViewController)

- (SWRevealViewController*)revealViewController;

@end

実装部

@implementation UIViewController(SWRevealViewController)

- (SWRevealViewController*)revealViewController
{
    UIViewController *parent = self;
//オブジェクトを生成 下記参照
    Class revealClass = [SWRevealViewController class];
    while ( nil != (parent = [parent parentViewController]) && ![parent isKindOfClass:revealClass] ) {}
    return (id)parent;
}

@end

オブジェクトを作るとき

オブジェクト = [ クラス名 初期化メソッド]

 //revealClass オブジェクトを生成
    Class revealClass = [SWRevealViewController class];

インスタンスを生成し初期化するとき

//dogにはDogクラスのインスタンスを作って初期化しなさい
dog = [[Dog alloc]init];


//このようにもかける
dogインスタンスには Dogクラスでインスタンス生成、メモリ領域を確保(ポインターという)*がつく
Dog *dog = [Dog alloc];

//生成したdog を初期化しなさい
dog = [dog init]

インスタンスは生成し、初期化しないと使えるようにならない。

ちなみにSwiftにはポインターは無い

便利ですね。