Hi Mike,

Thanks a lot for your feedback.
Your situation is quiet different from mine, BUT the way you override 
change_view and the related template will certainly help me to achieve what 
I need.
...and getting rid of dirty and unnecessary ajax calls.

I keep you posted.

Thx.

Karim

Le vendredi 1 mars 2019 00:06:40 UTC+1, Mike Dewhirst a écrit :
>
> On 28/02/2019 9:46 pm, [email protected] <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.
>     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
> class Assembly(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):
>         return ItemType.ASSEMBLY
>
>     class Meta:
>         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 [email protected] <javascript:>.
> To post to this group, send email to [email protected] 
> <javascript:>.
> 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/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.
>
>
>

-- 
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 [email protected].
To post to this group, send email to [email protected].
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/2482cf9f-5ee9-4ae8-9046-daca0d758e8e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to