文章列表
 
2011年12月26日 22:18
在上篇里面基本阐述了如何用python的方法 其实如果你的数据库足够先进还可以使用触发器trigger,调用相关的存储过程亦很容易记录这些历史记录

 
2011年12月22日 21:23

依据当初VB Delphi VC的经验,这个是要调用Win32 API的!

什么WM_DROPFILES消息、DragQueryFile(hDropInfo,0,buf,200);DragAcceptFile;DragFinish三大函数,依据这个来找QT解决方案,曲折不过也有解!

其实不必拉,QT已经給我做好了每个QWidget都已经设置了setAccoptDrag函数,配合event这个事件参数,例子参照

dropsite.py 见附件就怎么简单! QT不简单!!!

 

#!/usr/bin/env python

# This is only needed for Python v2 but is harmless for Python v3.

import sip

sip.setapi('QString', 2)

sip.setapi('QVariant', 2)

 

from PyQt4 import QtCore, QtGui

 

 

class DropArea(QtGui.QLabel):

 

    changed = QtCore.pyqtSignal(QtCore.QMimeData)

 

    def __init__(self, parent = None):

        super(DropArea, self).__init__(parent)

 

        self.setMinimumSize(200, 200)

        self.setFrameStyle(QtGui.QFrame.Sunken | QtGui.QFrame.StyledPanel)

        self.setAlignment(QtCore.Qt.AlignCenter)

        self.setAcceptDrops(True)

        self.setAutoFillBackground(True)

        self.clear()

 

    def dragEnterEvent(self, event):

        self.setText("<drop content>")

        self.setBackgroundRole(QtGui.QPalette.Highlight)

        event.acceptProposedAction()

        self.changed.emit(event.mimeData())

 

    def dragMoveEvent(self, event):

        event.acceptProposedAction()

 

    def dropEvent(self, event):

        mimeData = event.mimeData()

        if mimeData.hasImage():

            self.setPixmap(QtGui.QPixmap(mimeData.imageData()))

        elif mimeData.hasHtml():

            self.setText(mimeData.html())

            self.setTextFormat(QtCore.Qt.RichText)

        elif mimeData.hasText():

            self.setText(mimeData.text())

            self.setTextFormat(QtCore.Qt.PlainText)

        elif mimeData.hasUrls():

            self.setText("\n".join([url.path() for url in mimeData.urls()]))

        else:

            self.setText("Cannot display data")

 

        self.setBackgroundRole(QtGui.QPalette.Dark)

        event.acceptProposedAction()

 

    def dragLeaveEvent(self, event):

        self.clear()

        event.accept()

 

    def clear(self):

        self.setText("<drop content>")

        self.setBackgroundRole(QtGui.QPalette.Dark)

        self.changed.emit(None)

 

 

class DropSiteWindow(QtGui.QWidget):

 

    def __init__(self):

        super(DropSiteWindow, self).__init__()

 

        self.abstractLabel = QtGui.QLabel(

                "This example accepts drags from other applications and "

                "displays the MIME types provided by the drag object.")

        self.abstractLabel.setWordWrap(True)

        self.abstractLabel.adjustSize()

 

        self.dropArea = DropArea()

        self.dropArea.changed.connect(self.updateFormatsTable)

 

        self.formatsTable = QtGui.QTableWidget()

        self.formatsTable.setColumnCount(2)

        self.formatsTable.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)

        self.formatsTable.setHorizontalHeaderLabels(["Format", "Content"])

        self.formatsTable.horizontalHeader().setStretchLastSection(True)

 

        self.clearButton = QtGui.QPushButton("Clear")

        self.quitButton = QtGui.QPushButton("Quit")

 

        self.buttonBox = QtGui.QDialogButtonBox()

        self.buttonBox.addButton(self.clearButton, QtGui.QDialogButtonBox.ActionRole)

        self.buttonBox.addButton(self.quitButton, QtGui.QDialogButtonBox.RejectRole)

 

        self.quitButton.pressed.connect(self.close)

        self.clearButton.pressed.connect(self.dropArea.clear)

 

        mainLayout = QtGui.QVBoxLayout()

        mainLayout.addWidget(self.abstractLabel)

        mainLayout.addWidget(self.dropArea)

        mainLayout.addWidget(self.formatsTable)

        mainLayout.addWidget(self.buttonBox)

        self.setLayout(mainLayout)

 

        self.setWindowTitle("Drop Site")

        self.setMinimumSize(350, 500)

 

    def updateFormatsTable(self, mimeData=None):

        self.formatsTable.setRowCount(0)

 

        if mimeData is None:

            return

 

        for format in mimeData.formats():

            formatItem = QtGui.QTableWidgetItem(format)

            formatItem.setFlags(QtCore.Qt.ItemIsEnabled)

            formatItem.setTextAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)

 

            if format == 'text/plain':

                text = mimeData.text().strip()

            elif format == 'text/html':

                text = mimeData.html().strip()

            elif format == 'text/uri-list':

                text = " ".join([url.toString() for url in mimeData.urls()])

            else:

                text = " ".join(["%02X" % ord(datum) for datum in mimeData.data(format)])

 

            row = self.formatsTable.rowCount()

            self.formatsTable.insertRow(row)

            self.formatsTable.setItem(row, 0, QtGui.QTableWidgetItem(format))

            self.formatsTable.setItem(row, 1, QtGui.QTableWidgetItem(text))

 

        self.formatsTable.resizeColumnToContents(0)

 

 

if __name__ == '__main__':

 

    import sys

 

    app = QtGui.QApplication(sys.argv)

    window = DropSiteWindow()

    window.show()

    sys.exit(app.exec_())

 

 
2011年11月02日 1:38

利用simplejson和jQuery实现AJAX异步是非常容易的

step1,

def test(request):  # @url1

  ...

  return simplejson.dumps({'message':'Hello from Python!'})

step2,

<input id='test'/>

step3,

$.get(url1)

...

如此而已!!

 

但是作为程序员总希望创造自己的工具库,让上述步骤更通用、不重复。dajax就是这样的工具

官方主页在,http://dajaxproject.com/

该项目被分成两个部分 dajaxice 和 dajax。前者dajaxice实际上和上面提到的方法一样,只"前进"了一点点。用AJAX取回来的数据还要自己动手撰写js代码用于格式化到DOM组件上!

ajax.py

fromdjango.utils importsimplejson
fromdajaxice.decorators importdajaxice_register
 
@dajaxice_register
defdajaxice_example(request):
returnsimplejson.dumps({'message':'Hello from Python!'})

html

<inputname="rand"value="Get message from server!"id="rand"onclick="Dajaxice.examples.dajaxice_example(my_callback)"type="button">

javascript

functionmy_callback(data){
alert('Error');
}
 
dajax就进步了,我们可以完全在python(django)用类似jquery的风格自己决定客户端DOM组件的格式数据
fromdajax.core.DajaximportDajax
defassign_test(request):
dajax=Dajax()
dajax.assign('#block01 li','innerHTML','Something else...')
returndajax.json()

<divonclick="Dajaxice.app.assign_test(Dajax.process);">Click Here!</div>

Part II

django中除了上述的AJAX运用,其实我们还有很大一部分工作是Focus在Model的操作上。
这个github上也有现成的库- Django-ajax
主页 通过配置式的代码 非常容易就实现了Model的CRUD操作

 
2011年08月28日 16:09

 上篇我们讲到使用Simple History App是最便捷的,可是不能记录具体操作人的名字。那就改造她!

 

首先我们要获得当前用户的信息。在simple_history目录下创建middleware.py

try:
    from threading import local
except ImportError:
    from django.utils._threading_local import local

_thread_locals = local()
def get_current_user():
    return getattr(_thread_locals, 'user', None)

class ThreadLocals(object):
    """Middleware that gets various objects from the
    request object and saves them in thread local storage.
    """
    def process_request(self, request):
        _thread_locals.user = getattr(request, 'user', None)

注,有人反应这个发放对网站安全不好,不过考虑许多情况我们的应用是构架在内网的,忽略

 

修改simple_histrory的Model.py。SH使用的信号的方式触发行为的,

A,为history表添加用户名字段

    def create_history_model(self, model):
        """
        Creates a historical model to associate with the model provided.
        """
        attrs = self.copy_fields(model)
        attrs.update(self.get_extra_fields(model))
        attrs.update(Meta=type('Meta', (), self.get_meta_options(model)))
        attrs.update({'user':models.CharField(max_length=128)})  #ForeignKey(User)
        name = 'Historical_%s' % model._meta.object_name
        return type(name, (models.Model,), attrs)

 

B, 往数据表中添加用户名

    def create_historical_record(self, instance, type):
        manager = getattr(instance, self.manager_name)
        attrs = {}
        for field in instance._meta.fields:
            attrs[field.attname] = getattr(instance, field.attname)
        attrs['user'] = middleware.get_current_user().username
        manager.create(history_type=type, **attrs)
至此一个可以记录用户名的simple_history改造完成了

最后别忘了设置你的setting.py

MIDDLEWARE_CLASSES = (

    '.simple_history.middleware.ThreadLocals',

)

改造后的simple_history代码

 
2011年08月28日 12:33

先上案例,

   海报网    haibao.cn    定位“讲品味”的白领,生产内容(主要就是在网络上进行信息聚合),有了社区后 将流量导入到自己的商城。现在已经转卖给了估计媒体巨头。 推广方式除了传统的搜索引擎SEO优化,还参加诸如传统媒体的聚会、专题采访、颁奖晚会等等 

   绿色精品软件     http://www.portablesoft.org/    定位群体当时是“好奇、懂电脑”的男孩子拉。 推广渠道是新闻聚合订阅平台上展示(如QQ Read、Google Read)。主页上放置了广告,但是因为主题切入不准 怀疑盈利状况(淡然网游的广告还是算很精准的)

   奇趣发现  http://www.qiqufaxian.cn    专注各种新奇的玩意。QQ订阅是她重点的流量导入。盈利方式,侧栏 就是他从淘宝上的掘金方式,因为定位精准估计结果还是很好的

    

    以上的案例都是精准地找到自己擅长的细分、垂直市场,然后借力社会平台(Google、QQ、Taobao等等)成就自己的 !

     人于社会第一成本是机会,然后依次是时间和金钱。人们常识中往往颠倒这个顺序!

     当下我们听到太多负面容易让你泄气的信息。比如、我们的D异常的FB、比如国际经济形势严峻,大批的工厂倒闭。然而,经验(尤其是哪些时候总结的经验)告诉我,如今我们伟大的祖国仍处于上升通道!请用活在当下的心态对待自己的机会。许多时候可以的追求不跟风反而错失许多。

     小成本、薄人脉如何撬动人生机会 -- 生产! 生产实品或者生产内容均可。相对资本运作、生产是“辛苦”、“重复”、“薄利”、“波动”的代名词。在积累第一笔财富后的人多会考虑相对“轻松”“简单”“利厚”的生意,生产就是剩下来给我们的机会

     现状对知识产权保护不力,所以若要生产内容,这点是可以利用的。雇人翻译国外的网站!需要我们掌握的学习如何对这种雇员进行绩效考核。用目标驱动组织运营。

     最后,上述种种需要我们准备什么?

     大量的信息汲取。订阅20个以上你兴趣的博客,让自己坚持每天读完她们。上微薄、Sina微博(QQ就算了,除了八卦他得不到什么),更几个和你气味相投的人。若精力还充沛再功课完几个新闻组的贴。

     心理上。抛弃恐惧,让自己进入畅快淋漓、无所顾虑地行动。所谓利润是风险的兄弟(这活是我说 :) )

     工作中(若你还在打工潜水中)。有意识地拿当前工作练手以下能力:

     归纳总结然后决断能力。开始使用选择矩阵

     讲故事能力。若已经知道有许多工具可以让自己的邮件更具有表现力,那就毫不犹豫地运用她们,让自己熟练。定期用PPT来系统整理自己并向你的领导汇报自己)。让以上行为变成一种习惯、拒偷懒和凑合的形态。

   

     雷军说看5年,准备3年,做在当下。那么我们需要关注的“未来”又是什么? 

     智能机平台!是看谁能够最快、最优先在智能机布局好自己的“网络”、“通路”。比如你拥有一个上万用户的APP,可以让用户在手机能象电脑一样购物。那么Taobao上几亿卖家就会一定比例地向你交买路财。

 
   
 
 
文章存档
 
     
 
最新文章评论
  

很及时,谢谢!
 

回复leader20:没有
 

这个跟django版本有关系吗?
 

装了n回,才找到这个
 

你爱的我也爱
   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu