git 間違えて消してしまったファイルを全部 git checkout -- する。

環境

  • mac: 10.10.4
  • たいていのlinux はいけるでしょ。

gitでステージング済みのファイルを間違えてガッツリ削除してしまった場合、一つずつ git checkout -- file_name やるの辛い。 一行で delete された ファイルを checkout する。

% for i in $(git status | grep deleted | awk '{print $2}');do git checkout -- $i;done

ファイル名にdelete が含まれてたらcheckout -- してしまうのが難点ですが、そこはよろしくやりましょう。

djangoでユーザ情報編集後にユーザページにリダイレクトする

環境

  • django 1.8.7
  • python 3.4.1

ユーザ情報を編集後にユーザページにリダイレクトしたい。

が、ユーザページはuser id に紐付いていてユーザごとにURIが違うようときがあります。

success_url = ~~ として適当にやってたんですが、ちょっとまじめにユーザページにリダイレクトしてみます。

なお、User はカスタムしたoriginal_auth を利用。User でも同様に行けるはず。

views を修正

// original_auth/views.py

 from django.views.generic.edit import UpdateView
 from original_auth.models import OriginalUser

 class OriginalUserUpdateView(UpdateView):
     model = OriginalUser
     # リダイレクトさせるurl を動的に変更させるため、success_url の行をコメントアウト。
     # models.py にて get_absolute_url 関数を定義する。 
     # success_url = "/"
     context_object_name = 'user_data'
     fields = '__all__'
     exclude = ['password']

models を修正

// original_auth/models.py

 from django.contrib.auth.models import AbstractUser,AbstractBaseUser,PermissionsMixin,UserManager

 class OriginalUser(AbstractBaseUser,PermissionsMixin):
     :
    # get_absolute_url を次のように追加する
    def get_absolute_url(self):
        return "/user/%i/" % self.id

参考 https://docs.djangoproject.com/en/dev/ref/models/instances/#get-absolute-url

form投稿時にユーザ情報を外部キーを自動的に設定する

環境

  • django 1.8.7
  • python 3.4.1

ユーザがform 投稿する時に、外部キーを自動的に設定したい。しかも、ユーザには意識させずに。

例えば、次のようなUser を外部キーにもつTweet のデータがあるとする。

form を投稿した人を自動的にowner にするようにする。

修正前

//models.py

class Tweet(models.Model):
    ''' project to be donated'''
    name   = models.CharField(max_length=100) 
    owner  = models.ForeignKey(User)
    text   = models.TextField(blank=True)
    categories  = models.CharField(max_length=100,blank=True)
    created_at    = models.DateTimeField(auto_now_add=True, blank=True)
    updated_at    = models.DateTimeField(auto_now=True, blank=True)
    terminated_at = models.DateTimeField(auto_now=True, blank=True)

    def __unicode__():
        return self.name

修正後

// views.py

from .models import Tweet, TweetCreateForm
from django.contrib.auth import User


@login_required
def tweet_create(request):
    p = Tweet(owner=User.objects.get(pk=request.user.id))
    form = TweetCreateForm(request.POST or None, instance=p)
    form.save(commit=False)
    if form.is_valid():
        name = form.cleaned_data['name']
        text    = form.cleaned_data['text']

        form.save()
        return HttpResponseRedirect('/')
    else:
        return render(request, 'app/tweet_create.html', {'form': form})

models.py を修正する

// models.py

from django.db import models
from django.forms import ModelForm
from django import forms

class Tweet(models.Model):
    ''' project to be donated'''
    name   = models.CharField(max_length=100) 
    owner  = models.ForeignKey(User, editable=False) # 編集不可にする。form に表示されなくなる。
    text   = models.TextField(blank=True)
    categories  = models.CharField(max_length=100,blank=True)
    created_at    = models.DateTimeField(auto_now_add=True, blank=True)
    updated_at    = models.DateTimeField(auto_now=True, blank=True)
    terminated_at = models.DateTimeField(auto_now=True, blank=True)

    def __unicode__():
        return self.name

class TweetCreateForm(ModelForm):
    class Meta:
        model = Tweet
        fields = '__all__'

foregin key だと デフォルトで全部の選択肢(今回だと全ユーザ)からの選択可能な状態になってしまい、UXが悪い。 ユーザには意識させずに、自動的にひも付けができるのでいい感じかと。

もっと良い書き方があるかもしれないなぁ。。

【influxdb 0.9.x】 influxdbのインストール

時系列データベース influxdb 0.9.x のインストール方法

OSX

Mac OSX 10.8 以降であれば homebrew をつかってインストールしましょう。

brew update
brew install influxdb

launchctlで自動起動する場合

ln -sfv /usr/local/opt/influxdb/*.plist ~/Library/LaunchAgents
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.influxdb.plist

launchctlしないで手動で起動する場合

influxd -config /usr/local/etc/influxdb.conf

Ubuntu & Debian

# 64-bit system install instructions
wget http://influxdb.s3.amazonaws.com/influxdb_0.9.5.1_amd64.deb
sudo dpkg -i influxdb_0.9.5.1_amd64.deb

RedHat & CentOS

# 64-bit system install instructions
wget http://influxdb.s3.amazonaws.com/influxdb-0.9.5.1-1.x86_64.rpm
sudo yum localinstall influxdb-0.9.5.1-1.x86_64.rpm

あるいは

yum install http://influxdb.s3.amazonaws.com/influxdb-0.9.5.1-1.x86_64.rpm

参考

influxdb.com

【influxdb 0.9.x】 HTTP API経由でのinfluxdbへのデータ書き込み

データベース作成

mydb というデータベースを作成する

curl -G http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"

データ書き込み

データベース: mydb に下記データを書き込む

項目 意味
measurement cpu_load_short 関連するfield に保存されたデータについて記述したもの.string
tag key host, region key-value 型である tag の key の部分。string
tag value server01, us-west key-value 型である tag の value の部分。string
field key value key-value 型であるfield のkey の部分。string
field value 0.64 key-value 型であるfield のvalue の部分で、実際のデータに該当する。string, float, integer, or boolean
timestamp 1434055562000000000 データの時間。influxdbではすべてUTC
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'

複数データを一気に書き込む

このようにして複数データを一気に書き込むことができる

curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server02 value=0.67
cpu_load_short,host=server02,region=us-west value=0.55 1422568543702900257
cpu_load_short,direction=in,host=server01,region=us-west value=2.0 1422568543702900257'

ファイルのデータを書き込む

//cpu_data.txt
cpu_load_short,host=server02 value=0.67
cpu_load_short,host=server02,region=us-west value=0.55 1422568543702900257
cpu_load_short,direction=in,host=server01,region=us-west value=2.0 1422568543702900257

上記の cpu_data.txt を用意して, データベース mydb に書き込む

curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary @cpu_data.txt

ただし、5000 行を超えるようなデータの場合は複数ファイルに分割すべき。
デフォルトでは 書き込み timeout が5秒のため、timeoutを超えた場合に正常に書き込めたか確認取れないため。

スキーマ設計

influxdb はスキーマレスです。 いついかなるときでも新しい measurements, tags, and fields を追加することができます。
注意点としては前回の書き込みとは異なるデータ型で書き込んだ場合(前回はstring 型だったが、今回はfloat型の場合など)、influxdb は書き込みを拒否します。

HTTP response summary

  • 2xx
    • HTTP 204 No Content: 成功
    • HTTP 200 OK : influxdb はリクエストを解釈できるが完了できない. レスポンスボディに追加のエラー情報が含まれているはずです。
  • 4xx
    • InfluxDB はリクエストを解釈できません.
  • 5xx
    • システム高負荷か重大な障害にあっている.

https://influxdb.com/docs/v0.9/guides/writing_data.html

django generic view で login_required する

django 1.8.4

generic view で login_required するときは urls.py でデコレートする.

ログイン不要の場合

// app/urls.py
from django.conf.urls import patterns, url
from monitoring.models import Data
from monitoring.views import DataListView

urlpatterns = patterns('',
                 url(r'^$',
                 DataListView.as_view(model=Data),
                 name='data_list'
                ),
)

ログイン必要(login_required)の場合

// app/urls.py
  from django.conf.urls import patterns, url
  from monitoring.models import Data
  from monitoring.views import DataListView
+ from django.contrib.auth.decorators import login_required

  urlpatterns = patterns('',
                  url(r'^$',
-                 DataListView.as_view(model=Data),
+                 login_required(DataListView.as_view(model=Data)),
                   name='data_list'
                ),
)

http://stackoverflow.com/questions/2140550/how-to-require-login-for-django-generic-views

django genericviewで重複をなくして表示

django 1.8.4 python 3.4.1

次のようなモデルで name に重複した情報を入力することは可能だが、重複無しで表示したい。

// app/models.py
from django.db import models
class Data(models.Model):
    name   = models.CharField(max_length=20)  
    value  = models.CharField(max_length=20)  
    owner = models.CharField(max_length=20)

ListView でやりたいとする。

view にて get_context_data を継承する。

// app/views.py
from monitoring.models import Data
from django.views.generic import ListView, UpdateView, DetailView

class DataListView(ListView):
    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(DataListView, self).get_context_data(**kwargs)
        context['data_name'] = Data.objects.values('name').distinct()
        return context

template で次のように記載する。

// app/templates/app/data_list.html

{% for data in data_name %}

{{ data.name }}

{% endfor %}

これで重複無しでname を取得することができる。

http://docs.djangoproject.jp/en/latest/ref/models/querysets.html