django-cms / cms-template

A Django template for a typical django CMS installation
BSD 3-Clause "New" or "Revised" License
6 stars 1 forks source link

Use jQuery & Json response in plugin template #3

Open pooria-ghorbani opened 10 months ago

pooria-ghorbani commented 10 months ago

i want use jQuery in templates of plugin - this is good work, and return data, but don't link object fo new page in cms pattern , cms don't accept ,( pattern for click on plugin.objects with jQuery ) !!!!!!!!

fsbraun commented 10 months ago

I'm afraid, but I'm not sure if I understand your question. Using jQuery within plugins is certainly easily possible. I guess a regular pattern is to include a js library from your base.html. Can you describe what exactly you are trying to do and what fails?

pooria-ghorbani commented 10 months ago

i have plugin with name fighter , i use plugin form and pluginlist with child plugin for views list and details , i use AJAX in template for jQuery return data for list and details , in browser consol i have return data successfuly , but when select one object for details view , back 404 not openening page or when opening page , not in cms pattern , out of cms , can i use api restframework in django-cms for manage all urls or can u tell me how to opening details page in cms pattern ?

class FighterListPlugin(CMSPluginBase):
    model = FighterPluginModel
    form = FighterPluginForm
    name = _("FighterListPlugin")
    render_template = "fighter/fighter_list_plugin.html"
    child_classes = ['FighterPlugin']
    allow_children = True

plugin_pool.register_plugin(FighterListPlugin)
class FighterPlugin(CMSPluginBase):
    model = FighterPluginModel
    form = FighterPluginForm
    name = _("FighterPlugin")
    render_template = "fighter/fighter_plugin.html"
    parent_classes = ['FighterListPlugin']

    def render(self, context, instance, placeholder):
        fighters = Fighter.objects.all()
        if instance.country:
            fighters = fighters.filter(country=instance.country)
        if instance.sport:
            fighters = fighters.filter(sport=instance.sport)
        if instance.gender:
            fighters = fighters.filter(gender=instance.gender)
        if instance.champion:
            fighters = fighters.filter(champion=instance.champion)
        if instance.weight_class:
            fighters = fighters.filter(weight_class=instance.weight_class)
        context.update({'instance': instance, 'fighters': fighters})
        return context
    def copy_relations(self, old_instance: 'FighterPluginModel'):
        self.fighter = old_instance.fighter

plugin_pool.register_plugin(FighterPlugin)
<script>
    //  getFighter
    function getFighter(id) {
        jQuery.noConflict();
        jQuery(document).ready(function($) {
            $.ajax({
                url: "{% url 'get_fighter' %}" + id + "/",  // The URL of the view
                type: 'GET',  // The type of HTTP request
                success: function(data) {  // The function to run if the request is successful
                    // Create HTML for the fighter info
                    var fighterHtml = '<h2>' + data.name + '</h2><p>' + data.weight.toString() + '</p>';

                    // Add the fighter info to the page
                    $('#fighter-info').html(fighterHtml);
                },
                error: function() {  // The function to run if the request fails
                    console.log('Error fetching fighter data');
                }
            });
        });
    }
    jQuery.noConflict();
    jQuery(document).ready(function($) {
        $.ajax({
            url: "{% url 'get_fighters' %}",  // The URL of the view 
            type: 'GET',  // The type of HTTP request
            success: function(data) {  // The function to run if the request is successful
                // Create HTML for the fighter list
                var fighterListHtml = '';
                for (var i = 0; i < data.length; i++) {
                    fighterListHtml += '<a href="/fighterpage/" onclick="getFighter(' + data[i].id + '); return false;">' + data[i].name + '</a><br>';
                }
                // Check if the 'fighter-list' element exists
                if ($('#fighter-list').length) {
                    // Add the fighter list to the page
                    $('#fighter-list').html(fighterListHtml);
                } else {
                    console.log("'fighter-list' element does not exist");
                }
            },
            error: function() {  
                console.log('Error fetching fighters data');
            }
        });
    });
    </script>
fsbraun commented 10 months ago

Hm. That looks reasonable to me. What's your urls.py? It seems get_fighter is a registered url but not reachable.

pooria-ghorbani commented 10 months ago

i checked different pattern

urlpatterns = [
    path('get_fighter/', views.get_fighter, name='get_fighter'),
    path('get_fighter/<int:id>', views.get_fighter, name='get_fighter'),
    path('get_fighters/', views.get_fighters, name='get_fighters'),
    path('fighter/get_fighter/<int:id>/', views.get_fighter, name='get_fighter'), 
]

views :

def get_fighters(request):
    fighters = Fighter.objects.all().values('id', 'name')  # 
    data = list(fighters)
    return JsonResponse(data, safe=False)

def get_fighter(request, id):
    fighter = Fighter.objects.get(id = id)
    data = {
        'name': fighter.name,
        'weight': fighter.weight,
        #  other fields 
    }
    return JsonResponse(data)
fsbraun commented 10 months ago

Are those URL patterns before or after the CMS URLs: path('', include('cms.urls'))? The need to be before.

pooria-ghorbani commented 10 months ago

yes fighter url / before of CMS urls :

    path('admin/', admin.site.urls),
    path('filer/', include('filer.urls')),
    path('fighter/', include('backend.fighter.urls')),
    path('', include('cms.urls')),
pooria-ghorbani commented 10 months ago

I checked all the items several times, now I have a question! How can I pass all urls, even all cms pages, to rest_framework? I mean, all urls will work with rest_framework, is this possible? If not, how can I rest_framework my app so that when the data is taken, it will open in cms pages!? It's very easy in other cms but i am not sure working in django-cms !

fsbraun commented 10 months ago

If you want to access django CMS content (like pages) through rest, I'd check out djangocms-spa, a third-party package made to create single page applications with django CMS.

Regarding your 404 error, have you tried to replace url: "{% url 'get_fighter' %}" + id + "/" by url: "{% url 'get_fighter' %}" + id? For some reason, Django's URL resolver does not recognize it.

pooria-ghorbani commented 10 months ago

djangocms-spa not stable , no way to use api for return data on templates plugin , and apphook ? or config plugin without templates and use jquery for all request ??? i want fighter app use page for return all data ex /fighter/ = for list view , fighter/detail for details , and all url ,i search in django-cms but not find !!