Matthew

I think a workaround would be to reload the admin urls after each Stripe transaction. I don't know how to do that after looking at options.py etc.

I know I'm doing something adverse and it is spoiling the admin urls because the url in the address bar is correct but the page contents is empty. Refresh and shift-refresh doesn't do anything.

Saving a bit of source to reload runserver fixes (works around) the problem.

I'm happy to reveal as much source as necessary if you would like to see it and have the time.

Thanks very much for sticking with this

Mike

On 5/02/2019 2:19 am, Matthew Pava wrote:
The flow looks fine.  And when you click refresh on your browser on step 4 does 
the page refresh properly?

Perhaps it's a caching issue.
Are you wrapping the billing_payment_view with admin_view()?
https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls
 --> scroll towards the bottom of that section


-----Original Message-----
From: django-users@googlegroups.com [mailto:django-users@googlegroups.com] On 
Behalf Of Mike Dewhirst
Sent: Sunday, February 3, 2019 1:42 AM
To: django-users@googlegroups.com
Subject: Re: Admin form_url breakout problem

Matthew

I was wrong. I'm still in trouble. I thought it might be an incomplete
transaction so I tried making the the subscription.save() atomic but to
no avail.

Here is what happens ...

1.  Add an ingredient which is payable

2.  Save mixture

3.  SubstanceAdmin.change_view() establishes ...

      subscription = None
      if ingredient.is_payable():
          get or create a subscription record and populate it with fee,
gst etc.
          if the subscription.token field is blank (ie not paid):
              call billing_payment_view() which interfaces with Stripe
via a js popup and
                  a) gets a token in a hidden field
                  b) calls Stripe.charge(token) and gets a json charge
record back
                  c) populates the subscription.token field
                  d) saves the subscription record
                  e) creates a receipt record
                  f) sends an email receipt
                  g) puts thank you text and mixture url into context dict
                  h) calls billing_success_view(request, context) to
display success
                     message including link back to mixture
      return super(SubstanceAdmin, self).change_view()

4.  On clicking the back-to-the-mixture link in success.html, the Admin
brings
      up the Change Substance page without error but which is blank below the
      "Change Substance" heading. At that time the displayed URL in the
address
      bar is exactly correct.

5.  If the dev server reloads the page will paint properly if refreshed.

Theory:

The subscription record has been saved but not in a way which is visible
yet thereby confusing change_view() into thinking the token field is blank.

In other words the transaction needs to be committed
pre-billing_success_view()

In testing this it sadly this makes no difference.

Mike


On 2/02/2019 6:06 pm, Mike Dewhirst wrote:
I think I know. Don't waste time on this. I'll report back later.

Mike

On 2/02/2019 3:27 pm, Mike Dewhirst wrote:
I thought it was fixed but not so. It works perfectly *only* if the
dev server reloads after all the work and prior to clicking the link
on the success.html template back to the mixture (the substance with
ingredients).

I tried a workaround of making the link point to the substances list
page first. No difference. All substance pages come up blank.

When I reported earlier that it was working I must have changed some
text in a view to improve the screen wording and on saving the dev
server would have reloaded itself and that hid the problem.

The admin url is correct  ...

http://localhost:8000/admin/substance/substance/1442/change/

... but that refuses to display. There is no delay, no spinner. The
server console window shows nothing.

Not sure where to start looking.

Maybe something has corrupted Django's in-memory list of url patterns?

Is it caching?

Thanks for any non-javascript hints

Mike

On 30/01/2019 5:13 pm, Mike Dewhirst wrote:
Matthew

I looked for preventDefault and found it in lots of javascript
scripts. So I decided instead to look at my python code which is
slightly easier for me to understand. I sort of refactored it and
cut large swags out to simplify and inserted lots of print
statements. Then I thought I'd better read your advice again and try
harder to understand it.

The bit which made sense to me was ...

'let the admin handle it from there'

... I noticed that I was returning the billing payment_view. As soon
as I removed that 'return' and let the change_view return the super
call it started working.

Thank you very much for persisting with me.

The Admin is fabulous! Nobel prize for something is warranted :)

Much appreciated

Mike

On 29/01/2019 2:31 am, Matthew Pava wrote:
Hi Mike,
When Stripe processes the payment, you need to preventDefault on
the form submit, then add the token from Stripe to a hidden input
in your form without affecting any other data in the form.  Then
you can do form.submit() and let the admin handle it from there.
Check out the Stripe documentation for some good examples.  I've
used it myself.

-----Original Message-----
From: django-users@googlegroups.com
[mailto:django-users@googlegroups.com] On Behalf Of Mike Dewhirst
Sent: Friday, January 25, 2019 10:26 PM
To: django-users@googlegroups.com
Subject: Re: Admin form_url breakout problem

Matthew

I think I'll back everything out and start again. There must be a
basic
blunder somewhere.

Just talking it through, I can definitely launch payment_view from the
Admin when all the ducks are in a line. That view populates the hidden
..._id fields and Stripe API fields in the form then calls the Stripe
API which initiates the  Stripe javascript in the Payment template
which
resubmits the request with POST direct to Stripe so it can gather the
card detail and send back the json containing the token which
proves the
card worked. At that point payment is made and my payment_view has
lost
all the context because Stripe made the request not Django.
payment_view
detects the Stripe response and must reconstruct the model instances
from the data pre-placed in the hidden form fields. Once the instances
are retrieved that payment_view code updates the subscription record,
creates a receipt record , assembles a message for the success_view
and
sends an email to the user.

I am having trouble understanding the correct way to launch
payment_view
so that Admin doesn't get confused wanting to add payment/ to the url
and thus keeping it all within the Admin.

Regarding your comment on using reverse to derive the link, I agree. I
was just being somewhat paranoid and skipping the reverse code which I
haven't taken the time to study. I will.

Thanks again

Mike


On 26/01/2019 1:59 am, Matthew Pava wrote:
Based on the error message, it looks like you’re trying to call
reverse(‘admin’) somewhere, but that’s not in the code you shared.
Actually, you probably want to use a reverse call when populating
content[‘link’].

*From:*django-users@googlegroups.com
[mailto:django-users@googlegroups.com] *On Behalf Of *Mike Dewhirst
*Sent:* Friday, January 25, 2019 3:35 AM
*To:* django-users@googlegroups.com
*Subject:* Re: Admin form_url breakout problem

On 25/01/2019 2:40 am, Matthew Pava wrote:

      Hi Mike,

      I'm not really seeing why this is throwing errors at you.  It
seems like you've done everything right.  Could you provide the
code (or the relevant parts) for the Substance Admin form?

      Thanks!


Matthew

I'm still in trouble and including some code. I'm not being precious
about it just hoping not to overwhelm you. Please ask for the next
instalment ...

class SubstanceAdmin(admin.ModelAdmin):

      def subscribe(self, sm2mi, fee_type, fullyear=False):
          """
          sm2mi is the substance<-ingredient m2m through record
          fee_type determines the subscription fee amount
          fullyear=False means calculate the fee pro-rata to 30
September

          We don't need a request here so this can be imported from
elsewhere.
          Only called if a fee is payable. Only returns a subscription
if no token or
          fullyear == True meaning a subscription renewal is due
          """
          subscription, new = Subscription.objects.get_or_create(
              licensee=sm2mi.substance.division.company,
              ingredient=sm2mi.ingredient,
              fee_type=fee_type,
          )
          if not subscription.token or fullyear:
              return subscription

      def change_view(self, request, object_id, form_url='',
extra_context=None):
          """
          For the billing system we want to include all the context
data
so the
          change_form populates itself properly. See collect_content
          self = SubstanceAdmin
          request = wsgi request object
          object_id = substance
          form_url = no idea!
          extra_context = no_idea
          """
          sm2mis =
Substance_Ingredients.objects.filter(substance_id=object_id)
          for sm2mi in sm2mis:
              payable, fee_type = sm2mi.fee_payable()  # eg., True,
PAID_DATA
              if payable:
                  subscription = self.subscribe(sm2mi, fee_type)
                  if subscription:    # we need to collect money
for the
owner
                      self.change_form_template = 'payment.html'
                      content = collect_content(
                          sm2mi,
                          subscription,
                      )
                      return payment_view(
                          request,
                          sm2mi,
                          subscription,
                          content=content
                      )

          return super(SubstanceAdmin, self).change_view(
              request, object_id, form_url,
extra_context=extra_context,
          )

Here is the payment form ... which is further down in admin.py

      class IngredientsInline(admin.StackedInline):

          class PaymentForm(admin.StackedInline.form):
              sm2mi_id = forms.CharField(widget=forms.HiddenInput,
required=False)
              ingredient_id =
forms.CharField(widget=forms.HiddenInput,
required=False)
              subscription_id =
forms.CharField(widget=forms.HiddenInput, required=False)
              licensee_id = forms.CharField(widget=forms.HiddenInput,
required=False)

              stripeToken = forms.CharField(widget=forms.HiddenInput,
required=False)
              stripeEmail = forms.CharField(widget=forms.HiddenInput,
required=False)
              stripeBillingName =
forms.CharField(widget=forms.HiddenInput, required=False)
              stripeBillingAddressLine1 =
forms.CharField(widget=forms.HiddenInput, required=False)
              stripeBillingAddressZip =
forms.CharField(widget=forms.HiddenInput, required=False)
              stripeBillingAddressState =
forms.CharField(widget=forms.HiddenInput, required=False)
              stripeBillingAddressCity =
forms.CharField(widget=forms.HiddenInput, required=False)
              stripeBillingAddressCountry =
forms.CharField(widget=forms.HiddenInput, required=False)

          form = PaymentForm

All of the above is working so far as launching the Stripe javascript
popup and generating the receipt record correctly and so on but does
not return to the admin nor render the success page.

The try/except block in payment_view() barfs as follows ...

content['sm2mi'] = sm2mi
              content['receipt'] = receipt
              content['subscription'] = subscription
              content['message'] = mark_safe(display_message)
              content['link'] =
'/admin/substance/substance/{0}/change/'.format(
                  sm2mi.substance.id
              )
              # report success to the card payer
              try:
                  return render(
                      template_name='success.html',
                      context=content,
                      request=request,
                  )
              except Exception as err:
                  print('\n327 billing.views %s' % err)


327 billing.views Reverse for 'admin' not found. 'admin' is not a
valid view function or pattern name.


Thanks for looking at it

Mike







--
You received this message because you are subscribed to the Google
Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it,
send
an email to django-users+unsubscr...@googlegroups.com
<mailto:django-users+unsubscr...@googlegroups.com>.
To post to this group, send email to django-users@googlegroups.com
<mailto:django-users@googlegroups.com>.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/c70b8afa-6c7b-07b8-3f5d-ec2da8047951%40dewhirst.com.au

<https://groups.google.com/d/msgid/django-users/c70b8afa-6c7b-07b8-3f5d-ec2da8047951%40dewhirst.com.au?utm_medium=email&utm_source=footer>.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google
Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it,
send
an email to django-users+unsubscr...@googlegroups.com
<mailto:django-users+unsubscr...@googlegroups.com>.
To post to this group, send email to django-users@googlegroups.com
<mailto:django-users@googlegroups.com>.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/7adfa5a476904a0e884e6e5ab9a42171%40iss2.ISS.LOCAL

<https://groups.google.com/d/msgid/django-users/7adfa5a476904a0e884e6e5ab9a42171%40iss2.ISS.LOCAL?utm_medium=email&utm_source=footer>.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/3093737e-3da1-4ea7-b55a-c6e13283fd18%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

Reply via email to