On 2/03/2019 2:08 am, karim.at...@gmail.com wrote:
Hi Mike,
I tried what you wrote by overriding the *self.change_form_template*
but the form does not appear.
Would you please provide me the content of your model admin
*billing_payment_view ?*
Sure. I recently asked for assistance here and posted most of the code ...
https://groups.google.com/forum/#!topic/django-users/809HBmPa9vk
You are right, my application is different. My template contains a
script provided by Stripe which calls their API to collect a credit card
payment. But overall it isn't much different than any other template
called by any other view. The view just takes a different path depending
on whether it is a POST or a GET request. My view looks complex because
when the user clicks [Pay now] it happens in the Stripe js embedded in
the template and the Stripe API - in turn - hits my view with the actual
POST containing the result of the credit card transaction. I had to seed
the form/template with hidden data so it travelled across the Stripe
boundary and back to me so I could complete the processing. If you can
see past that complication it should be clear that I'm using the form to
clean the data and the view to interface with the ORM/database.
It is working well for me now and I'm in the middle of writing unit tests.
Good luck
Thanks.
Karim
Le vendredi 1 mars 2019 00:06:40 UTC+1, Mike Dewhirst a écrit :
On 28/02/2019 9:46 pm, karim...@gmail.com <javascript:> wrote:
Hi,
I'm currently struggling with a custom ModelAdmin.
Karim
I haven't tried to fully understand your use case. However, this
is what I think your process could be if you do not wish to ajax
it ...
1. Override the model save() method to call a model method which
detects your trigger scenario and calls the code you wish to
execute to collect all the data you wish to display. This might be
in the parent model or the m2m 'through' model. Unlikely to be in
the child model.
2. Write a Form to reveal the data you wish to display. It
probably needs to be a ModelForm
3. Write a template for the data including any hidden fields for
object pks and additionally consider calling {{ block.super }} to
display inherited stuff if you are extending another template and
using the same block. When I first started to work all this out I
was able to get my form to appear at the top of the ModelAdmin
form using block.super and spent a bit of time hiding the big red
[Delete] button because it was too close to my big blue [Pay now]
button. However, as I got deeper into it I somehow lost that and
never got it back. I was so pleased with getting it working
eventually that I persuaded myself I didn't really want it on the
same page anyway. Your mileage may vary :) I think you need to
hard-code the form in the ModelAdmin to get it appearing above
everything else.
4. Write any necessary urls
5. Write a view to manipulate your data, based on the request and
your form
6. Get the Admin to display it on demand. The first line of the
change_view() method below initialises the ModelAdmin to do
absolutely nothing different than usual. Nothing will happen
unless the trigger is detected. Then finally call to super to
resume the normal course of events when your code is complete.
What follows is my own recent experience. The comments should tell
you more than the code
def change_view(self, request, object_id, form_url='', extra_context=None):
""" self = SubstanceAdmin
request = wsgi request object
object_id = substance
form_url = no idea!
extra_context = dict of apps, models, admin_urls and permissions
https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django
<https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django>.
contrib.admin.ModelAdmin.change_view
"""
# Let the ModelAdmin resume normal operations with its own template
self.change_form_template = None
# queryset of m2m records from the 'through' table
ingredients =
Substance_Ingredients.objects.filter(substance_id=object_id)
subscription = None
for sm2mi in ingredients:
# sm2mi.fee_payable() is the detector which triggers the process
payable, fee_type = sm2mi.fee_payable() # eg., True, PAID_DATA
if payable:
# generate a subscription record with blank token field or
# if one exists with a non-blank token, return None
subscription = billing_subscribe(sm2mi, fee_type)
if subscription: # collect money for the owner
# switch the ModelAdmin to the new template
self.change_form_template = 'payment.html'
# assemble all the necessary data for the view
context = billing_collect_context(
sm2mi,
subscription,
)
# get everything into the payment_view context
if not extra_context:
extra_context = dict()
extra_context.update(self.admin_site.each_context(request))
extra_context.update(context)
# wrap the view to protect it with Admin permissions
self.admin_site.admin_view(
# call the view with request and context
billing_payment_view(
request,
sm2mi,
subscription,
context=extra_context,
)
)
# only one sm2mi at a time
break
return super(SubstanceAdmin, self).change_view(
request, object_id, form_url, extra_context
)
7. Call super in the model save() method *or* raise an exception
to prevent saving. I'm actually not sure about this bit. It may go
against the Django flow. However, I do use a BusinessRuleViolation
exception which inherits from ValidationError and therefore lets
me include a human readable message which appears in the Admin and
*seems* to prevent saving. You would need to test this especially
with m2m side-effects and atomicity consequences.
I hope this helps.
Mike
Considering the following model:
|
# Bloc fonctionnel
classAssembly(Item):
product
=models.ForeignKey(to='ProductFamily',on_delete=models.CASCADE,null=True,verbose_name=_('Famille
Produit'))
functions
=models.ManyToManyField(Function,verbose_name=_('Fonctions'))
*performances*=models.ManyToManyField(Performance,verbose_name=_('Performances'),related_name='performances')
def_get_type(self):
returnItemType.ASSEMBLY
classMeta:
verbose_name =_('Bloc Fonctionnel')
verbose_name_plural =_('Blocs Fonctionnels')
|
I have a custom AssemblyAdmin related to it and also a custom
AssemblyForm for customizing some fieds.
The *performances* m2m field is critical.
The performances are captured in the form with a dynamic_raw_id
field, which works fine.
But when this field is modified, some updates/deletions might be
applied in other tables of the database.
For this purpose, I need to collect the "performance" pk captured
in the html form and compare them with those currently in the
database.
Basically, when the user clicks on the regular "Save" or "Save
and continue" button, I would need to display an alert form (like
when you click on the delete button) to explain what would happen.
I struggled with some ajax routines but it does not work as
expected.
I don't know if it's really doable and how to achieve it.
Any suggestion is welcome.
Cheers.
Z.
--
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...@googlegroups.com <javascript:>.
To post to this group, send email to django...@googlegroups.com
<javascript:>.
Visit this group at https://groups.google.com/group/django-users
<https://groups.google.com/group/django-users>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/88135218-a965-46c8-a454-c0376a5682f1%40googlegroups.com
<https://groups.google.com/d/msgid/django-users/88135218-a965-46c8-a454-c0376a5682f1%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout
<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/ba1fe4cd-420b-4683-be97-469c303deb86%40googlegroups.com
<https://groups.google.com/d/msgid/django-users/ba1fe4cd-420b-4683-be97-469c303deb86%40googlegroups.com?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/1a32b6c9-8c7e-0abe-57f7-0f20630580d7%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.