不要多次触发我的方法

时间:2017-07-19 20:24:24

标签: python django

models.py

class Contract(TimeStampedModel):
    customer = models.ForeignKey('customers.CustomerProfile')
    template = models.ForeignKey('configurations.ContractTemplate')
    product = models.OneToOneField('products.CustomerProduct')
    signed_at = models.DateTimeField(_('Date signed'), blank=True, null=True)
    cancelled_at = models.DateTimeField(_('Date cancelled'), blank=True,
                                        null=True)
    html_source = models.TextField(_('HTML source'), blank=True, null=True)
    pdf_file = models.OneToOneField('documents.Meta', on_delete=models.SET_NULL,
                                    blank=True, null=True)
    is_signed = models.BooleanField(_('Is signed'), default=False)
    is_cancelled = models.BooleanField(_('Is cancelled'), default=False)
    signature_uuid = models.UUIDField(_('Signature UUID'), primary_key=False,
                                      default=uuid.uuid4, editable=False)
    signature_ip = models.GenericIPAddressField(_('Signature IP'), blank=True,
                                                null=True)

...

    def sign(self, ip):
        from loanwolf.contracts.utils import render_html_contract, store_pdf_contract
        self.html_source = render_html_contract(self.template, self.customer,
                                                self.product)
        store_pdf_contract(self)
        self.signature_ip = ip
        self.signed_at = datetime.datetime.now()
        self.is_signed = True
        self.save()
        if self.request.state.is_signature:
            self.request.sign()
        return True

views.py

class ContractAsHtmlView(DetailView):
    model = Contract
    pk_url_kwarg = 'uuid'

    def get_object(self, queryset=None):
        try:
            return self.model.objects.get(
                signature_uuid=self.kwargs.get('uuid'))
        except self.model.DoesNotExist:
            return None

    def render_to_response(self, context, **response_kwargs):
        if self.request.GET.get('lang'):
            lang = self.request.GET.get('lang')
        else:
            lang = translation.get_language_from_request(self.request)
        if self.object.template.language == lang:
            template = self.object.template
        else:
            try:
                template = ContractTemplate.objects.get(
                    slug=self.object.template.slug, language=lang)
            except ContractTemplate.DoesNotExist:
                template = self.object.template
        html = render_html_contract(
            template, self.object.customer, self.object.product)
        return HttpResponse(html)

    def get_context_data(self, **kwargs):
        import ipdb; ipdb.set_trace()
        context = super(ContractAsHtmlView, self).get_context_data(**kwargs)

        context.update({
            'signature_ip': self.viewing_signature_ip,
        })

    @property
    def viewing_signature_ip(self):
        import ipdb; ipdb.set_trace()
        contract = Contract.objects.get(pk=1)
        if contract.sign == True:
            return contract.signature_ip

目前,sign()方法返回一个布尔参数,但不能多次触发。因此,我无法在view if contract.sign == True:中使用该方法。无论如何,sign()需要参数,而不是属性。还有另一种方法可以在不再触发它的情况下调用sign()吗?我可以使用某种指标或信号做这样的事情吗?

清楚,sign()用于程序中的其他位置。如果view_signature_ip()为真,我想对sign()方法说,而不是返回contract.signature_ip

1 个答案:

答案 0 :(得分:1)

好的,让我们看看。你的财产方法有一个错误:

@property
def viewing_signature_ip(self):
    import ipdb; ipdb.set_trace()
    contract = Contract.objects.get(pk=1)
    if contract.sign == True:
        return contract.signature_ip

您正在检查方法定义,该方法定义始终为True;)如果要检查方法的结果,则必须调用它:if contract.sign() == True: - )

如果您想避免调用sign,可以使用合约实例的is_signed属性:if contract.is_signed

每次访问属性时都会调用方法属性:contract = Contract.objects.get(pk=1)的另一个问题,您可能希望在视图属性中缓存合同的结果:

    _signature_ip = None

    @property
    def viewing_signature_ip(self):
        import ipdb; ipdb.set_trace()
        if self._signature_ip is not None:
             return self._signature_ip

        contract = Contract.objects.get(pk=1)

        self._signature_ip = contract.signature_ip if contract.is_signed else ''
        return self._signature_ip