如何在网站上模态的组件中显示我的自定义模型字段?

How can I display my custom model fields within the components of a modal on a website?

提问人:LAHCEN AGLAGAL 提问时间:9/21/2023 更新时间:10/3/2023 访问量:60

问:

我对如何从后端模型中检索数据并将其显示在我的网站上感到有些困惑。例如,我正在使用网站模型提供的拖放组件。如何在网站的轮播中显示自定义模型中的数据(如图像)?此外,我想知道如何提交网站表单并将提交的数据插入到我的自定义模型中。任何指导将不胜感激!

好吧,我正在尝试为用户创建一个完全自定义的页面。

蟒蛇 odoo odoo-14 qweb odoo-官网

评论


答:

0赞 sylvain 10/2/2023 #1

在自定义(覆盖)控制器中,您可以返回 request.render(“a-model.view-key”, data),以便将自定义模型数据发送到网站模板 “a-model.view-key”...以官方website_blog插件为例:

website_blog/控制器/主.py

class WebsiteBlog(http.Controller):
#...
@http.route(['''/blog/<model("blog.blog", "[('website_id', 'in', (False, current_website_id))]"):blog>/post/<model("blog.post", "[('blog_id','=',blog[0])]"):blog_post>''',
    ], type='http', auth="public", website=True)
    def blog_post(self, blog, blog_post, tag_id=None, page=1, enable_editor=None, **post):
        """ Prepare all values to display the blog.

        :return dict values: values for the templates, containing

         - 'blog_post': browse of the current post
         - 'blog': browse of the current blog
         - 'blogs': list of browse records of blogs
         - 'tag': current tag, if tag_id in parameters
         - 'tags': all tags, for tag-based navigation
         - 'pager': a pager on the comments
         - 'nav_list': a dict [year][month] for archives navigation
         - 'next_post': next blog post, to direct the user towards the next interesting post
        """
        if not blog.can_access_from_current_website():
            raise werkzeug.exceptions.NotFound()

        BlogPost = request.env['blog.post']
        date_begin, date_end = post.get('date_begin'), post.get('date_end')
        #pager = ...
        comments = blog_post.website_message_ids[pager_begin:pager_end]
        domain = request.website.website_domain()
        blogs = blog.search(domain, order="create_date, id asc")
        tag = request.env['blog.tag'].browse(int(tag_id))
        blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end)

        if not blog_post.blog_id.id == blog.id:
            return request.redirect("/blog/%s/post/%s" % (slug(blog_post.blog_id), slug(blog_post)), code=301)

        tags = request.env['blog.tag'].search([])

        # Find next Post
        blog_post_domain = [('blog_id', '=', blog.id)]
        if not request.env.user.has_group('website.group_website_designer'):
            blog_post_domain += [('post_date', '<=', fields.Datetime.now())]

        all_post = BlogPost.search(blog_post_domain)

        if blog_post not in all_post:
            return request.redirect("/blog/%s" % (slug(blog_post.blog_id)))

        # should always return at least the current post
        all_post_ids = all_post.ids
        current_blog_post_index = all_post_ids.index(blog_post.id)
        nb_posts = len(all_post_ids)
        next_post_id = all_post_ids[(current_blog_post_index + 1) % nb_posts] if nb_posts > 1 else None
        next_post = next_post_id and BlogPost.browse(next_post_id) or False

        values = {
            'tags': tags,
            'tag': tag,
            'blog': blog,
            'blog_post': blog_post,
            'blogs': blogs,
            'main_object': blog_post,
            'nav_list': self.nav_list(blog),
            'enable_editor': enable_editor,
            'next_post': next_post,
            'date': date_begin,
            'blog_url': blog_url,
             #'pager': pager,
            'comments': comments,
        }
        response = request.render("website_blog.blog_post_complete", values)

        #...
        return response

这个 controller-def 返回 xml-template “blog_post_complete”(并注入其:blog、tags、next_post...),它位于 views/website_blog_templates.xml 下的模块 “website_blog” 中:

<template id="website_blog.blog_post_complete" name="Blog Post">
    <t t-call="website_blog.index">

        <!-- Check for active options: the stored value may be used in sub-templates too  -->
        <t t-set="opt_blog_post_readable" t-value="request.website.viewref('website_blog.opt_blog_post_readable').active"/>
        <!-- t t-set=...  -->


        <section id="o_wblog_post_top">
            <div id="title" class="blog_header" t-ignore="True">
                <t t-call="website.record_cover">
                    <t t-set="_record" t-value="blog_post"/>
                    <t t-set="use_filters" t-value="True"/>
                    <t t-set="use_size" t-value="True"/>
                    <t t-set="use_text_size" t-value="True"/>
                    <t t-set="additionnal_classes" t-value="'o_wblog_post_page_cover'"/>

                    <div class="container text-center position-relative h-100 d-flex flex-column flex-grow-1 justify-content-around">
                        <div t-attf-class="o_wblog_post_title #{opt_blog_post_select_to_tweet and 'js_tweet'} #{opt_blog_post_select_to_comment and 'js_comment'}">
                            <div t-field="blog_post.name" id="o_wblog_post_name" data-oe-expression="blog_post.name" t-att-data-blog-id="blog_post.id" placeholder="Blog Post Title"/>
                            <div t-field="blog_post.subtitle" id="o_wblog_post_subtitle"  placeholder="Subtitle"/>
                        </div>
                        <a id="o_wblog_post_content_jump" href="#o_wblog_post_main" class="css_editable_mode_hidden justify-content-center align-items-center rounded-circle mx-auto text-decoration-none">
                            <i class="fa fa-angle-down fa-3x text-white" aria-label="To blog content" title="To blog content"/>
                        </a>
                    </div>
                </t>
            </div>
        </section>

        <section id="o_wblog_post_main" t-attf-class="container pt-4 pb-5 #{'anim' in request.params and 'o_wblog_post_main_transition'}">
            <!-- Sidebar-enabled Layout -->
            <div t-if="opt_blog_post_sidebar" t-attf-class="mx-auto #{opt_blog_post_readable and 'o_wblog_read_with_sidebar'}">
                <div t-attf-class="d-flex flex-column flex-lg-row #{opt_blog_post_readable and 'justify-content-between'}">
                    <div id="o_wblog_post_content" t-attf-class="#{opt_blog_post_readable and 'o_wblog_read w-100 flex-shrink-0' or 'w-lg-75'}">
                        <t t-call="website_blog.blog_post_content"/>
                    </div>
                    <div id="o_wblog_post_sidebar_col" t-attf-class="pl-lg-5 #{not opt_blog_post_readable and 'flex-grow-1 w-lg-25'}">
                        <t t-call="website_blog.blog_post_sidebar"/>
                    </div>
                </div>
            </div>

            <!-- No-Sidebar Layout -->
            <div t-if="not opt_blog_post_sidebar" t-attf-class="mx-auto #{opt_blog_post_readable and 'o_wblog_read'}">
                <div class="d-flex flex-column flex-lg-row">
                    <div id="o_wblog_post_content" t-attf-class=" #{opt_blog_post_readable and 'o_wblog_read w-100 flex-shrink-0'}">
                        <t t-call="website_blog.blog_post_content"/>
                    </div>
                </div>
            </div>
        </section>
        <section id="o_wblog_post_footer"/>
    </t>
</template>

要显示您的自定义模型字段,您可以继承控制器并覆盖其 def 并扩展视图(使用 inherit_id)...

from odoo.addons.website_blog.controllers.main import WebsiteBlog

class MyWebsiteBlog(WebsiteBlog):

    def blog_post(self, blog, blog_post, tag_id=None, page=1,  enable_editor=None, **post):

        #...
        # get original values from the def of the parent controller: super(MyWebsiteBlog)
        res = super(MyWebsiteBlog, self).blog_post(blog, blog_post, tag_id=None, page=1, enable_editor=None, **post)
        values = res.qcontext 
        # add your custom field value to the original values dictionary:
        values['my_custom_field'] = my_custom_value
        # pass these updated values to the original template:
        response = request.render("website_blog.blog_post_complete", values)