Показаны сообщения с ярлыком django. Показать все сообщения
Показаны сообщения с ярлыком django. Показать все сообщения

среда, 10 октября 2012 г.

Применение классов при получении подробного решения онлайн

Задался Я целью сделать симплекс метод онлайн с подробным бесплатным решением.

Как известно, обычно, подробное решение должно быть разбито на шаги, чтобы стало ясно.

Чтобы было ясно и у меня в коде и чтобы не запутаться при написании такой сложной программы я ввел класс. Входящими параметрами в этот класс стали:
  • функция, для которой необходимо найти экстремум
  • этот экстремум является максимумом или минимумом
  • и система условий в симплекс-задаче в ввиде списка данных (python-словарей)
В __init__ (в конструкторе) инитятся какие-то глобальные вещи, например, свободные члены, искусственные переменные, преобразуются данные к удобным.

Далее, для каждого шага проверяется:
  • нужно ли выполнять соотв. шаг (в отдельном методе объекта данного класса).
  • В другом методе для данного шага выполняется преобразование входящих данных
  • записывается состояние (слепок) данных на каком-то шаге в свойство объекта класса. (Например, запоминаются данные после приведения системы условий к каноническому виду, как требует симплекс-метод)
  • Также в каком-то из методов для данного шага (на проверке или же преобразовании данных) - заполняются глобальные вещи, например, свободные переменные
 У нас всегда есть проходящие данные через все методы и куча слепков этих данных.

Далее полученный объект данного класса пихается в django-шаблон, где происходит вывод решения задачи симплекс методом простыми манипуляциями if и for.

Пример того, что получилось вы можете посмотреть по ссылке симлекс метод онлайн
(там есть текстовый пример, чтобы не скучали и видео пример)

суббота, 10 декабря 2011 г.

django import excel

This publication is present of django system for import data from excel:

Use this step by step for rapid start use wih django application:

1. Follow to page https://github.com/satels/django-import-excel and push the button Watch
2.Download this project https://github.com/satels/django-import-excel/zipball/master
3. Unpack, following to the folder and run pip install -e . or python setup.py install
4. In settings.py:

INSTALLED_APPS = [
     ...
     'import_excel',
     ...
]

5. So, for example, you need  import the data from excel for model


class Book(models.Model):

    name = models.CharField(max_length=255)
    author = models.CharField(max_length=255)


The excel file contains the data

name | author
Tom Sawyer | Mark Twain
The Sands of Mars | Arthur C. Clarke

To do is, create this form:

from django.db import transaction
from import_excel.forms import ImportExcelForm


class BookImportForm(ImportExcelForm):

    @transaction.autocommit
    def update_callback(self, request, converted_items):
         for book_item in converted_items[:1]:
              name = book_item[0]
              author = book_item[1]
              Book.objects.create(name=name, author=author)


Далее, в urls.py:

urlpatterns = patterns('',
      url(r'^/books/import-from-excel/$', permission_required('books.add_book')(import_excel), {
             'FormClass': BookImportForm, 'next_url': '/books/', 'with_good': True, 'template_name': 'import_excel/import_excel.html',
      }, name='book-import-excel'),
),


We see this in import book form , next_url - the url of page for redirect after succefull import request, with_good - it means, what must pre moderate data from excel file, also you must set template_name, if you have custom template (copy file from import_excel/templates/import_excel/import_excel.html)

P.S. permission_required for django admin zone

django импорт excel

Появилась очень удобная система для импорта данных из excel в django:

Чтобы начать использовать это приложение django в своем проекте:

1. Переходим на страницу https://github.com/satels/django-import-excel и нажимаем кнопку Watch
2.Скачиваем проект себе https://github.com/satels/django-import-excel/zipball/master
3. Распаковываем, переходим в папку и запускаем pip install -e . или же python setup.py install
4. В settings.py:

INSTALLED_APPS = [
     ...
     'import_excel',
     ...
]

5. Итак, например, нам надо импортировать данные из excel для модели


class Book(models.Model):

    name = models.CharField(max_length=255)
    author = models.CharField(max_length=255)


Файл excel же содержит данные

name | author
Мастер и Маргарита | Михаил Булгаков
И дольше века длится день | Чингиз Айтматов

Для этого создаем форму

from django.db import transaction
from import_excel.forms import ImportExcelForm



class BookImportForm(ImportExcelForm):

    @transaction.autocommit
    def update_callback(self, request, converted_data):
         for book_item in converted_data[1:]:
              name = book_item[0]
              author = book_item[1]
              Book.objects.create(name=name, author=author)


Далее, в urls.py:

urlpatterns = patterns('',
      url(r'^/books/import-from-excel/$', permission_required('books.add_book')(import_excel), {
             'FormClass': BookImportForm, 'next_url': '/books/', 'with_good': True, 'template_name': 'import_excel/import_excel.html',
      }, name='book-import-excel'),
),


Видим здесь мы указываем форму для загрузки книг, next_url - страницу для перехода после успешной загрузки, with_good - это значит, что надо подтвердить загружаемые данные с предварительным просмотром, также вы можете указывать template_name, если захотите задать свой (скопируйте файл из import_excel/templates/import_excel/import_excel.html)

вторник, 25 октября 2011 г.

Склонятор имен на django

Склонятор имен на django можно найти по ссылке https://github.com/gugu/django-declension. Использует api яндекс склонятора http://nano.yandex.ru/project/inflect/ Кэширует результат в таблицу базы данных, имеется templatetag.

среда, 5 октября 2011 г.

django-excel - отдаем excel красиво

Старая классная вещь (2010 года) от kmike - django-excel-response Для того, чтобы отдать excel из django как http response - просто составляем список списков, или же передаем объекты модели django и получаем готовый excel Ссылка: https://bitbucket.org/kmike/django-excel-response

Для загрузки же используйте django-import-excel

суббота, 9 июля 2011 г.

django-qiwi. Платежная система на django - киви. SOAP-сервер

Итак, как же установить и запустить платежную систему qiwi на django. Делаем все по шагам и у вас получится.
Здесь не рассматриваются шаги по регистрации в системе qiwi. Здесь рассматривается техническая часть (Хотелось бы только сказать, что в кабинете qiwi нужно включить soap)

Скачиваем и устанавливаем приложение

  1. Скачиваем отсюда https://github.com/satels/django-qiwi/zipball/master
  2. Распаковываем
  3. Устанавливаем
    python setup.py install
Или же все одним шагом
pip install -e git://github.com/satels/django-qiwi.git#egg=django-qiwi

Делаем установки django-qiwi в ваш проект.

В settings.py django-проекта
INSTALLED_APPS = [
    ...
    'django_qiwi',
    ...
]

#qiwi soap
QIWI_APP = 'qiwi'
QIWI_LOGIN = '12345'
QIWI_PASSWORD = 'SecretPAroli'
QIWI_SOAP_SERVER = ('0.0.0.0', 17555)

Здесь вы указываете QIWI_APP backend-приложение (app), который будет обрабатывать ваши объекты счетов и платежей (про это ниже)
Про логин и пароль все ясно.
Далее, QIWI_SOAP_SERVER - здесь указывается хост и порт, на которых будет запускаться qiwi soap сервер для обработки оповещений со стороны QIWI.

Интегрируем с вашей системой платежей (счета, платежи)

  1. Прикручиваем форму для создания платежа (Мы сообщаем QIWI о создании счета)
  2. Делаем Backend-приложение (QIWI сообщает нам - удачно или нет прошел платеж)

Форма создания платежа

Вот как обрабатывается у меня создания платежа
from django_qiwi import get_status_text
from django_qiwi.soap.client import Client as QiwiClient
...
                client = QiwiClient()
                code = client.createBill(
                    phone=client_phone,
                    amount=sum,
                    comment=comment,
                    txn=invoice.id,
                    lifetime=datetime.now() + timedelta(1),
                )
                if code in [0, 50]:
                    return redirect(invoice.get_qiwi_url())
                else:
                    messages.error(request,
                       MESSAGE_QIWI_ERROR % get_status_text(code)
                    )
                    buy_denial_by_invoice(invoice)
...

Видно, что создаем платеж и оповещаем через soap - оповещаем друзей роботов из QIWI,
при удачном исходе - код 0 или 50 - переадресуем клиента на страницу с инструкцией, как оплатить, или же сообщаем о ошибке и отменяем платеж.

Что же такое указано в QIWI_APP?

Теперь, как же будет нас оповещать qiwi о удачном платеже. Будет через backend, который мы создали и указали в переменной QIWI_APP
Указан пакет в вашем проекте django. Структура такая:
qiwi
    __init__.py
или такая
qiwi.py
Содержание qiwi примерно такое будет у вас (Я взял из своего проекта)
from discounts.utils import buy_denial_by_invoice, buy_paided_by_invoice
from django.conf import settings
from django_qiwi.soap.client import Client as QiwiClient
from invoices.models import Invoice
import datetime
import logging


def update_bill(txn, status):
    client = QiwiClient()
    response = client.checkBill(txn)
    code = response['status']
    amount = response['amount']
    amount = float(amount)
    invoices = Invoice.objects.filter(
        id=txn, status=Invoice.STATUS.nopaid, type='qiwi',
    )
    if invoices.exists():
        invoice = invoices[0]
        if code == 60:
            buy_paided_by_invoice(invoice, amount)
            ret = 0
        elif code in [150, 160, 161]:
            buy_denial_by_invoice(invoice)
            ret = 0
        else:
            ret = -1
    else:
        ret = 210
    logging.basicConfig(filename=settings.QIWI_LOG_FILE, level=logging.DEBUG)
    dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    message = 'date: %s, txn: %s, code: %s, amount: %s, ret:%s' % (
        dt, txn, code, amount, ret
    )
    logging.debug(message)
    return ret

Т.е. вот здесь проверяется при оповещении о платеже - есть ли неоплаченный платеж, то если есть, то оплачиваем его, если пришло оповещение о оплаченном платеже или же не оплачиваем.
Такж же можем сообщить, что платежа не существует

Запускаем тесты

При каждом последующем изменении кода - запускаем тесты, чтобы точно ничего не отвалилось при оплате у клиента
Создаем подмену для QIWI - мы будем отсылать оповещения ему о создании платежа
#coding:utf-8
from django_qiwi.soap import server
from settings import QIWI_PASSWORD, QIWI_LOGIN
from threading import Thread
import SOAPpy
import qiwi

class QiwiProviderThread(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.setDaemon(True)
        self.server = self._createSOAPServer()
        self.data = {}
        self.paid = False

    def _createSOAPServer(self):
        server = SOAPpy.SOAPServer(('localhost', 77877))

        def createBill(login, password, user, amount, comment, txn, lifetime, alarm, create):
            if not all([login==QIWI_LOGIN, password==QIWI_PASSWORD]):
                return 150
            if len(user) != 10:
                return 150
            try:
                amount = float(amount)
            except:
                return 150
            if amount > 15000:
                return 242
            if alarm not in [0, 1, 2]:
                return 150
            if create not in [0, 1]:
                return 150
            self.data = {
                'user': user,
                'amount': amount,
                'comment': comment,
                'txn': txn,
                'lifetime': lifetime,
                'alarm': alarm,
                'create':create,
                'date': datetime.now().strftime("%d.%m.%Y %H:%M:%S")
            }
            return 50

        def checkBill(login, password, txn):
            if txn != self.data['txn']:
                return 210
            res = dict(self.data, **{
                'status': self.paid and 60 or 52
            })
            return res

        server.registerFunction(createBill)
        server.registerFunction(checkBill)
        return server

    def run(self):
        self.server.serve_forever()

    def stop(self):
        self.server.shutdown()
        del self.server
        self.join()

    def bayWithQiwi(self, txn, amount):

        lifetime = self.data['lifetime']

        if datetime.strptime(lifetime, '%d.%m.%Y %H:%M:%S') < datetime.now():
            raise ValueError(u'Нельзя оплатить. Срок оплаты прошел')

        self.paid = True
        self.data['amount'] = str(amount)

        qiwi.update_bill(txn=txn, status=60)

- запускается поток, который запускает подмену soap серверу системы. Даже есть подмена клиенту, который пошел оплачивать через терминал QIWI! (bayWithQiwi). Сам тест
class QiwiBayTest(test.TestCase, _InvoiceTest, _BayTest, _QiwiTest):

    def setUp(self):
        super(QiwiBayTest, self)._setUp()
        self.qiwi_provider = QiwiProviderThread()
        self.qiwi_provider.start()
        initial = self.default_initial
        self.default_initial = dict(initial, **{'payment_method': 'qiwi'})

    def tearDown(self):
        super(QiwiBayTest, self)._tearDown()
        self.qiwi_provider.stop()

    def testBayWithQiwiAmountLessThenPrice(self):
        """Оплачиваем скидку через QIWI, но кладем меньшую сумму, чем надо"""
        response = self._postData(self.default_initial)
        invoice = self._assertExistQiwiInvoice()
        self._assertFollowToQiwiInvoicePage(response, invoice)
        amount = self.discount.price_paid*0.8
        self.qiwi_provider.bayWithQiwi(invoice.id, amount)
        self._refreshUser()
        invoice = self._getRefreshedInvoice(invoice)
        self._assertParentInvoiceNoPaid(invoice)
        self._assertUserBalance(amount + self.initial_sum)
        invoice.delete()

    def testBayWithQiwiAmountGreateThenPrice(self):
        """Оплачиваем скидку через QIWI, но кладем большую сумму, чем надо"""
        data = self.default_initial
        response = self._postData(data)
        invoice = self._assertExistQiwiInvoice()
        self._assertFollowToQiwiInvoicePage(response, invoice)
        amount = self.discount.price_paid*data['number'] - self.initial_sum
        self.qiwi_provider.bayWithQiwi(invoice.id, amount)
        self._refreshUser()
        invoice = self._getRefreshedInvoice(invoice)
        self._assertParentInvoicePaid(invoice)
        self._assertUserBalance(0.0)
        invoice.delete()

    def testBayWithQiwiAndBalanceGreateThenPrice(self):
        """Оплачиваем скидку через QIWI, при этом баланс на счете большой"""
        data = self.default_initial
        sum = self.discount.price_paid*data['number']
        update_balance(self.user, sum)
        balance_before = self.user.get_profile().get_balance()
        response = self._postData(data)
        invoice = self._assertExistQiwiInvoice()
        self._assertFollowToQiwiInvoicePage(response, invoice)
        amount = self.initial_sum
        self.qiwi_provider.bayWithQiwi(invoice.id, amount)
        self._refreshUser()
        invoice = self._getRefreshedInvoice(invoice)
        self._assertParentInvoicePaid(invoice)
        self._assertUserBalance(balance_before + amount - sum)
        invoice.delete()

    def testSomeErrorOnQiwiProvider(self):
        """Ошибка на сервере QIWI, например, превышена сумма платежа(> 15000)"""
        data = dict(self.default_initial, **{
            'number': int(16000.0/self.discount.price_paid)
        })
        response = self._postData(data)
        self._assertFollowToBayPage(response)
        self._assertCountMessages(response, 1)
        invoice = self._assertExistQiwiInvoice()
        self._assertParentInvoiceDenial(invoice)

    def _assertExistQiwiInvoice(self):
        return self._assertExistInvoiceByType('qiwi')
Не забудьте в файле test_settings.py (настройках settings.py для тестов) указать примерно такое from settings import * QIWI_SOAP_ISHOP_URL = 'http://localhost:77877' QIWI_SOAP_SERVER = ('localhost', 17777) А потом запускать так ./manage.py test --settings="test_settings.py"

Запускаем сервер soap для взаимодействия с qiwi

Чтобы просто попробовать, как работает - запускаем так: python manage.py run_qiwi_soap В продакшн версии нужно запускать подобное через sv (что такое sv): Используем файл из приложения django_qiwi: https://github.com/satels/django-qiwi/blob/master/qiwi_soap_server.sh.example Далее, создаем /etc/service/qiwi_soap_server/run и делаем его исполняемым, копируем содержание файла qiwi_soap_server.sh.example в него

Запускаем
sv u qiwi_soap_server

Все должно работать. Пишите комментарии

суббота, 25 июня 2011 г.

Ускорение тестов в django

Если у вас имеется проект django, в котором имеется порядка 100 тестов с созданием 100 объектов, то можно использовать для ускорения тестов модуль для django:
https://gist.github.com/1044215 - там в doc-комментарии написано как применять
В нашем проекте тест ускорился в 20 раз

вторник, 7 июня 2011 г.

django-zpayment

django-zpayment - это модуль, написанный на python для интеграции платежной системы Z-Payment в проектах django.

0. Установка
Сначала скачиваем приложение:
Перейти по ссылке https://github.com/satels/django-zpayment/zipball/master
или выполнить команду
git clone git://github.com/satels/django-zpayment.git

Устанавливаем
cd django-zpayment
pip install -e .

1. В settings.py в INSTALL_APPS устанавливаем webmoney и zpayment
INSTALLED_APPS = (
...
'webmoney',
'zpayment',
)

2. В настройках переменные
В settings.py
# Настройка Z-Payment
ZPAYMENT_SHOP_ID = 'XXXX' # Номер магазина
ZPAYMENT_PASSWORD_INITIALIZATION = 'Your_Password' # Пароль инициализации магазина
ZPAYMENT_SECRET_KEY = 'Secret_Key' # Секретный ключ Merchant Key

Брать отсюда:
Z-Payment Номер магазина
Z-Payment параметры url секретные коды, пароли
3. Добавить кошелек (описано на сайте Z-Payment)
Кратко:
Добавить кошелек на сайте https://z-payment.ru/register.php, добавить магазин https://z-payment.ru/cabinet_shops.php, получить нормальный атестат

4. Генерить пароли с помощью утилиты с контрольной работы (или лучше с калькулятора)
Для генерирования паролей в кабинете рекомендую использовать Генератор паролей (Generate Passwords)

5. Для создания платежа для покупки используется форма PaymentRequestForm, пример использования формы создания платежа на сайте:
from webmoney.models import Invoice as WebmoneyInvoice
from zpayment.forms import get_zp_sign, PaymentRequestForm

def bay(request):
...
if payment_method == 'zpayment':
payment_no = 55 # Уникальный номер платежа на вашем сайте (например, номер выставленного счета)
total = 14.4 # Сумма покупки
payment_no = invoice.id
zp_sign = get_zp_sign(payment_no, total) # Формируется секретный hash (Исправить )
comment = u'Pokupka skidki %s' % translify(discount.name)
initial = {
'LMI_PAYMENT_AMOUNT': total,
'LMI_PAYMENT_NO': payment_no,
'LMI_PAYMENT_DESC': comment, #Комментарий в windows-1251
'CLIENT_MAIL': email,
'ZP_SIGN': zp_sign
}
form = PaymentRequestForm(initial=initial)
webmoney_invoice = WebmoneyInvoice.objects.create(user=user)
webmoney_invoice.payment_no = payment_no
webmoney_invoice.save()
template_name = 'zpayment/zpayment_form.html'
return render_to_response(template_name, {
'form': form
}, context_instance=RequestContext(request))

Где шаблон zpayment/zpayment_form.html:
{% extends "base.html" %}
{% block title %}Z-payment. Перенаправление...{% endblock %}
{% block head %}
<script type="text/javascript" src="{{ MEDIA_URL }}js/zpayment.js"></script>
{% endblock %}
{% block content %}
<h1>Перенаправление на страницу оплаты Z-Payment..</h1>
<form method="POST" action="https://z-payment.ru/merchant.php" id="zpayment-form">
<div style="display:none;">
  {{ form.as_p }}
</div>
<noscript>
<input type="submit" value="Перейти к оплате" />
</noscript>
</form>
{% endblock %}

использует автоматический POST submit формы с помощью jquery.
Содержание zpayment.js:
$(function() {
$("#zpayment-form").submit();
})


6. Ссылки для того, куда робот Z-Payment будет оповещать размещаем в urls.py
urlpatterns = patterns('',
...
url(r'^zpayment/', include('zpayment.urls')),
...
)


7. Про кодировку windows-1251
Комментарии к платежам нужно писать в кодировке windows-1251. Хотя я использую pytils.translit.translify(description)
8. Про POST при создании платежа.
Обязательно выставляем в настройках на сайте z-payment.ru обработку всех параметров через POST
9. Написать про success и fail
10. Про signals

Для обработки информации, пришедшей после покупки

from webmoney.signals import webmoney_payment_accepted

def webmoney_payment_accepted_processor(sender, payment, **kwargs):
print payment # Здесь как то используем webmoney_payment объект
# Например, сохраняем счета, выставляем статус оплачено

webmoney_payment_accepted.connect(webmoney_payment_accepted_processor)

P.S. К большой радости мне выдали аттестат разработчика z-payment!

суббота, 4 июня 2011 г.

Опыт покупки сайта про автомобили

Решил купить сайт с продаж http://mashina.net.ru про автомобили, тюнинг и фото автомобилей.
Расскажу про свой опыт покупки подобного сайта.
Что требовалось:
Осуществить безопасную сделку при покупке. А именно - человек передает мне сайт - доменное имя, контент, базу и код сайта, но загвоздка была в том, что если я передам деньги раньше, то чел может мне ничего не передать и скрыться, или наоборот - чел на меня оформит домен и передаст сайт, а я ему ничего не перечислю.
Тут выхода три пришло нам в голову в процессе обсуждения данной проблемы:

  1. Использовать сервис pr-cy.ru по покупке продаже сайтов

  2. Использовать сервис webmoney - там есть платежи с протекцией, тем более у бывшего владельца сайта про тюнинг хороший атестат webmoney

  3. Использовать yandex деньги - там тоже есть протекция, но ни один из нас не использовал данный способ


Итак, pr-cy отпал, т.к. чел уже размещал сайт и повторное размещение там через месяц чтоли. Да еще там в аське молчат, в скайпе не всегда берут трубку, а также когда пишешь - тоже молчат. Пишешь на почту - тоже молчат. Вообщем отстойно работают ребятки
webmoney отпал, после того как я вспомнил, что имелся печальный опыт - у меня было два аккаунта (пароли постоянно теряются от вебмоней) - и надо было подверждать какой-то аккаунт - для этого надо словить посредника - прийти с паспортом, оплатить ему, да еще если уговоришь! Вообщем я решил не рисковать, да еще и комиссия при переводе от пользователя пользователю 0.8% - много. Зато выяснил про пополнение безпроцентное в webmoney - на сайте самарском через альфа-банк (https://wmcasher.ru/alfabankin)
Оставался лишь третий вариант yandex Деньги - пароли не теряются, т.к. можно сохранять пароли в браузере, и делать лишь единый мастер-пароль на браузер (я использую мозилу), там есть протекция, а также безпроцентное пополнение yandex денег через Евросеть. А также процент перевода между пользователями оказался 0.5%. Выбрал этот вариант.

1. Итак, чел мне скинул фото, контент, код, также указал ns сервера на мои для домена.
2. Я перевел с протекцией платеж
3. Сейчас ожидаю, когда домен мне передаст (в ник.ру увижу домен в своем списке, но и спрошу у ник.ру, кто сейчас администратор)
4. Отправлю код протекции челу.
И все - сделка завершена.

При переносе фотографий авто контента и кода, а также базу на сервер все оказалось ок.
Чел мне передал через docs.google.com (залил, расшарил, а я скачал)
Я скачал, распаковал (т.к. при распаковке на сервере выводится плохая кодировка)
Заливать на сервер стал с помощью rsync (в linux, ubuntu). Залил.
Установил файл в нужную директорию, установил из дампа базу. Повалились ошибки php (Давно не работал с php, поэтому не сразу смог решить в чем дело - пришлось искать решение проблемы в интернете) - оказалось, что настройки php.ini по-умолчанию не совсем подходят для данного сайта.

Что предполагаю сделать:
На django реализовать весь функционал, что сейчас есть на сайте, также добавить интернет-магазин, объявления о покупке и продаже автомобилей.

пятница, 3 июня 2011 г.

Работа с doc, pdf, odt, html в django

Иногда нам нужно формировать документы динамически в django проекте.
Хотелось бы иметь общий формат документа, из которого можно было бы в легкую переводить в doc (word), pdf, html форматы.
В проекте django-webodt был выбран формат ODF.
Описание проекта из README:
django-webodt - это django модуль для создания документов различных форматов из формата Open Document Templates.
Django-webodt поддерживает виртуально все форматы через backend приложения. Есть позитивный опыт создания PDF, HTML, RDF and MS Word (.doc) документов.

Конверсия документов производится с помощью внешних приложений, где приложения работают в django-webodt через backend's

ooffice: Используется опенофис для конвертирования в различные форматы. Опен офис должен быть запущен как демон.

abiword: легковесный конвертер, но результат выглядит не очень красиво для сложных документов (проверено на практике)

googledocs: используется бесплатный сервис Google. Имеются вроде как ограничения в ресурсах, а также нужно регистрироваться в Google.


Итак, что нужно делать, чтобы начать работать с django-webodt:
  1. Установка:
    pip install django-webodt

  2. В settings.py проекта django:
    INSTALLED_APPS = (
    ...
    'webodt',
    )
  3. Для примера - используем abiword
    WEBODT_CONVERTER = 'webodt.converters.abiword.AbiwordODFConverter'

  4. Укажем, где искать шаблоны odt
    WEBODT_TEMPLATE_PATH = '.../webodt/templates/'

  5. Укажем, где искать шаблоны odt
    WEBODT_TEMPLATE_PATH = '.../webodt/templates/'

  6. Использование
    $ ./manage.py shell
    >>> from django.template import Context
    >>> import webodt
    >>> template = webodt.ODFTemplate('test.odt')
    >>> context = dict(user='John Doe', balance=10.05)
    >>> document = template.render(Context(context))

    Документ
    >>> document
    <open file '/tmp/tmpL0AKCV.odt', mode 'rb' at 0xa7c39ec>

    Это реальный файл
    >>> document.__class__
    <class 'webodt.ODFDocument'>
    >>> import os
    >>> os.path.isfile(document.name)
    True
    >>> document.close()
    >>> os.path.isfile(document.name)
    False
    Установите delete_on_close=False в render, чтобы документ не удалялся

  7. Пример конвертирования в pdf:
    >>> document = template.render(Context(context))
    >>> from webodt.converters import converter
    >>> conv = converter()
    >>> pdf = conv.convert(document, format='pdf')
    >>> pdf
    <open file '/tmp/tmpYuAhhN.pdf', mode 'r' at 0xa7c3dfc>

Недавно мы сделали, чтобы можно было редактировать шаблоны-документы прямо в libreoffice (но включать бекенд под название опен офис надо) - раньше надо было править content.xml внутри odt.
Только надо быть внимательнее с тегами, такими как if - вставлять их под одним тегом, чтобы структура файла xml не нарушилась и документ не сломался.
Также скоро появится коммит, чтобы можно было вставлять цикл, подобный for прямо тоже как при обычном редактировании odt-файла в libreoffice.

Итак, чтобы использовать openoffice бакенд - используем команду в shell
soffice '-accept=socket,host=127.0.0.1,port=2002;urp;StarOffice.NamingService' -headless
, в это в settings.py проекта django для настройки
OOFFICE_SERVER = ('127.0.0.1', 2002)
WEBODT_CONVERTER = 'webodt.converters.openoffice.OpenOfficeODFConverter'


Для использования сервиса google:
WEBODT_CONVERTER = 'webodt.converters.googledocs.GoogleDocsODFConverter'


Постоянная ссылка на документацию:http://packages.python.org/django-webodt/

Update: Если хотим получить документ html без скачивания, то передаем параметр inline=True в render_to_response:
render_to_response(..., inline=True)
Update 2: Заместо soffice лучше использовать libreoffice.

четверг, 14 апреля 2011 г.

asynchronous database tornado (async) django

В проектах онлайн общений, онлайн игр в движках этих проектов требуется асинхронное обращение к базе. Асинхронная работа увеличивает скорость работы проекта и не дает повиснуть или заткнуться движку.

Например, в tornadio или tornado при асинхронном общении с клиентом - требуется как раз такое подключение к базе.

Поискав в интернете - нашел приложение по обращению к базе данных database через http-протокол
dbslayer. Там - посылаешь sql-запрос через http - получаешь ответ в виде json. Неудобство - этот самый json и неочевидность - как же его поставить.

Для django и python программистов Я решил сделать подобное dbslayer django-async-dbslayer - там пишем orm-запрос, посылаем его и ждем уже удобный ответ в виде serialize queryset.

Пример использования django-async-dbslayer
Например, нам требуется получить всех пользователей в игре.
class SomeController(object):
def games_game_info(self):
UserInGame.dbslayer.filter(
game__id=self.game.pk
).select_related('game', 'user').async(callback=self._send_game_info)
def _send_game_info(self, response):
objects = deserialize(response.body)
count_users = len(objects)
game = objects[0].game
members = [{
'user_id': obj.user.pk,
'name': obj.name,
'position': obj.position,
'turn': obj.turn,
'on_community': obj.on_community,
'passed': obj.passed,
'current_bet': obj.current_bet,
'online': obj.user.pk in [
s.user.pk for s in self.s.gamers.get(self.game.pk, [])
]
} for obj in objects]
game_info = {
'_view': 'games_game_info',
'count_users': count_users,
'state': game.state,
'current_trump': game.current_trump,
'members': members
}
self._send_all(game_info)


_send_all - посылает ответ браузеру (socket.io)

django-async-dbslayer умеет использовать почти все методы queryset (кроме aggregate и annotate). Также есть возможность посылать запросы пачками

Мой знакомый развил тему и намного улучшил - сделал систему tornado-slacker

среда, 6 апреля 2011 г.

Создал игру тысяча онлайн на django, tornadio

Создал игру 1000 онлайн с использованием django и tornadio.

Посмотреть результат можно по ссылке http://games.kontrolnaya-rabota.ru/igra1000online/.
Необходимо три игрока, чтобы игра началась.
Скоро выложу примеры как реализовавывал и с помощью чего реализовывал.

пятница, 1 апреля 2011 г.

TinyMCE + FILEBROWSER в DJANGO 1.3. + GRAPPELLI

Теперь установить связку tinymce + filebrowser в admin-части в django 1.3 стало проще некуда:))
+ Для красоты еще grappelli

Для примера я напишу какие у меня в проекте установлены конфиги:

Устанавливаем с помощью pip приложения
$ pip install django-filebrowser==3.1 django-grappelli==2.3.2

В settings.py: (В Apocalepse комментирует... в INSTALLED_APPS перечилить приложения в порядке: filebrowser и grappelli должны идти до contrib.admin)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'filebrowser',
'grappelli',
'django.contrib.admin',
'wpages',
'users',
)
...
STATIC_ROOT = STATICFILES_ROOT = at_project_root('static')

STATIC_URL = STATICFILES_URL = '/static/'

ADMIN_MEDIA_PREFIX = STATIC_URL + "grappelli/"


Здесь at_project_root('static') - папка static относительно корневой папки проекта django.

В файле admin.py приложения проекта:
class MyAdmin(admin.ModelAdmin):
...
class Media:
...
js = [
'/static/grappelli/tinymce/jscripts/tiny_mce/tiny_mce.js',
'/static/grappelli/tinymce_setup/tinymce_setup.js',
]

Apocalepse: В urls.py:
urlpatterns = patterns(
...
(r'^grappelli/', include('grappelli.urls')),
(r'^filebrowser/', include('filebrowser.urls'))
)

Все. Теперь осталось только запустить команду
$ python manage.py collectstatic

Заходим в админку и видим примерно следующую картину:
tinymce в admin django








django filebrowser



Выбор файла в django filebrowser


Update:

Как установить tinymce в данной связке?


Для установки tinymce в связке django, filebrowser, grappelli достаточно:
1. скачать tinymce c официального сайта http://tinymce.moxiecode.com/download/download.php
2. Положить по пути, например, /static/grappelli/tinymce/jscripts/tiny_mce/tiny_mce.js
3. Указать путь /static/grappelli/tinymce/jscripts/tiny_mce/tiny_mce.js в MyAdmin.Media.js, как указанно здесь

воскресенье, 21 ноября 2010 г.

django-comepay

Продам модуль для django для платежной системы comepay за 9990 руб.

четверг, 18 ноября 2010 г.

Платежная система на django

Прикручу платежные системы на django: robokassa, qiwi, mgpe, комепей (comepay) для вас всего за 45990 руб. Обращаться на satels@gmail.com

django-qiwi (soap)

Прикручу django-qiwi (soap) - модуль django для QIWI (КИВИ) через протокол SOAP (с обратной связью). Стоимость 19990 руб. Обращаться на satels@gmail.com

Update: Скачать можно бесплатно и пользоваться https://github.com/satels/django-qiwi
Пример, как можно все прикрутить здесь

django-mgpe

продам django-mgpe - для платежной системы МГПЕ.
Цена 9990 руб. Обращаться на email: satels@gmail.com

Update: Бесплатно можно скачать отсюда https://github.com/satels/django-mgpe

среда, 24 марта 2010 г.

Обновление-синхронизация модели и базы в Django

Обновление (синхронизация) базы и модели в Django в стандартной комплектации нельзя произвести. Команда
python manage.py syncdb

только создает таблицы, но не обновляет при соотв. изменениях в модели. Приходится удалять таблицы и снова запускать вышеуказанную команду.
Но выход есть в использовании south (http://south.aeracode.org/):
  • Устанавливаем:
    sudo easy_install south
  • В INSTALLED_APPS добавляем:
    'south',
  • Допустим, чтобы синхронизовать добавленное поле title_small в articles.Article
    $ python manage.py schemamigration articles title_section --add-field Article.title_small
    $ python manage.py migrate articles
    Здесь title_section - это имя миграции

вторник, 23 февраля 2010 г.

django markitup

Мне нравится редактор markitup, Стал его использовать в django в adminке.
Чтобы его установить в консоли набираем:
sudo easy_install django_markitup
Из преимуществ перед другими редакторами - я считаю, что это высокая скорость работы, присутствие быстрых клавиш.
Markitup больше подойдет для владельцев сайтов, которые знают html. Но есть версии и с посредственным редактированием html
Попробовать разные варианты редактора можно тут
Django проект тут

вторник, 9 февраля 2010 г.

Права на объекты в django

Недавно в django появилась возможность делать права на отдельные объекты.
Пример:
Нам надо, определять - имеет ли пользователь право читать данный объект. В backends.py делаем:

class ReaderBackend(object):

supports_object_permissions = True

def has_perm(self, user, perm='r', obj=None):
if obj.is_reader(user):
return True
return False

def authenticate(self):
pass

, где параметр supports_object_permissions = True как раз определяет поддержку прав на объекты

Во views.py:

@login_required
def tasks_list_by_tag(request, project_slug, tag_id):

project = get_object_or_404(Project, slug=project_slug)
if not request.user.has_perm('r', project):
return HttpResponseRedirect(project.get_noaccess_url())
...


В settings.py:

AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'backends.ReaderBackend',
...
)