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, 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.
>     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 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.
> 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 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/2482cf9f-5ee9-4ae8-9046-daca0d758e8e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to