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

问题描述 投票:0回答:1

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

嗯,我正在尝试为用户创建一个完全定制的页面。

python odoo odoo-14 qweb odoo-website
1个回答
0
投票

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

website_blog/controllers/main.py

@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_url = "/blogpost/%s" % blog_post.id

        pager = request.website.pager(
            url=pager_url,
            total=len(blog_post.website_message_ids),
            page=page,
            step=self._post_comment_per_page,
            scope=7
        )
        pager_begin = (page - 1) * self._post_comment_per_page
        pager_end = page * self._post_comment_per_page
        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 = None
        if tag_id:
            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

此控制器调用 xml 模板“blog_post_complete”,该模板位于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>

© www.soinside.com 2019 - 2024. All rights reserved.