`_get_page`实例化Page class

时间:2018-05-29 10:59:56

标签: django

我正在通过阅读Django源代码来学习编码风格:
在pagination.py Pagination中,源代码定义了一个实例化类Page的私有方法。

def page(self, number):
    """
    Returns a Page object for the given 1-based page number.
    """
    number = self.validate_number(number)
    bottom = (number - 1) * self.per_page
    top = bottom + self.per_page
    if top + self.orphans >= self.count:
        top = self.count
    return self._get_page(self.object_list[bottom:top], number, self)


def _get_page(self, *args, **kwargs):
    """
    Returns an instance of a single page.

    This hook can be used by subclasses to use an alternative to the
    standard :cls:`Page` object.
    """
    return Page(*args, **kwargs)

如果将方法页面实例化为

,我认为它更具可读性
def page(self, number):
    """
    Returns a Page object for the given 1-based page number.
    """
    number = self.validate_number(number)
    bottom = (number - 1) * self.per_page
    top = bottom + self.per_page
    if top + self.orphans >= self.count:
        top = self.count
    return Page(self.object_list[bottom:top], number, self)

在额外步骤中定义单独_get_page方法的优势是什么?

2 个答案:

答案 0 :(得分:4)

优点是,就像docstring所说的那样(你也在你的问题中显示):

  

子类可以使用此挂钩来使用标准的替代方法:cls:Page object。

如果我们只想更改Page课程,我们会覆盖_get_page(),但不要重复构建topbottom参数的整个逻辑在page()方法(DRY principle)。

只有当我们想要更改那里计算的逻辑的某些部分时,我们才会覆盖page()方法。

答案 1 :(得分:4)

它已经在函数的评论中:

<Page.Resources>
    <ControlTemplate x:Key="BlurEditFlyout">
        ....
        <ComboBox ItemsSource="{Bind it to the _esaingType}" />
        ....
    <ControlTemplate x:Key="BlurEditFlyout">
</Page.Resources>

<GridView ItemsSource="{x:Bind _items}">
    <GridView.ItemTemplate>
        <DataTemplate x:DataType="local:MethodData">
            <StackPanel>
                ....
                <Button Visibility="{x:Bind EditButtonVisibility}">
                    <Button.Flyout>
                        <Flyout>
                            <Flyout.FlyoutPresenterStyle>
                                <Style TargetType="FlyoutPresenter">
                                    <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
                                    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
                                </Style>
                            </Flyout.FlyoutPresenterStyle>
                            <ContentControl Template="{x:Bind FlyoutTemplate}"/>
                        </Flyout>
                    </Button.Flyout>
                    <SymbolIcon Symbol="Edit"/>
                </Button>
                ....
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

想象一下,稍后您编写自己的分页方法(使用更高级的public sealed partial class MainPage : Page { ObservableCollection<MethodData> _items = new ObservableCollection<MethodData>(); List<string> _easingType = new List<string>(Enum.GetNames(typeof(EasingType)).ToArray()); Dictionary<MethodName, ControlTemplate> _buttonFlyoutDictionary = new Dictionary<MethodName, ControlTemplate>(); public MainPage() { this.InitializeComponent(); LoadFlyoutResources(); _items.Add(GetMethodData(MethodName.Blur)); } private void LoadFlyoutResources() { _buttonFlyoutDictionary.Add(MethodName.Blur, (ControlTemplate)Resources["BlurEditFlyout"]); ..... } private MethodData GetMethodData(MethodName methodName) { _buttonFlyoutDictionary.TryGetValue(methodName, out ControlTemplate flyoutTemplate); return new MethodData(methodName, flyoutTemplate); } } public class MethodData { public string Name { get; set; } public ControlTemplate FlyoutTemplate { get; set; } public Visibility EditButtonVisibility { get; set; } public MethodData(MethodName name, ControlTemplate flyoutTemplate) { Name = name.ToString(); FlyoutTemplate = flyoutTemplate; EditButtonVisibility = (name == MethodName.Then) ? Visibility.Collapsed : Visibility.Visible; } } public enum MethodName { Blur, .... } 对象),那么您不仅需要使用新的{{1}来修复所有您的代码对象(也许有些人仍然需要使用&#34; &#34;页面对象),但你也必须修补Django代码库的某些部分。

通过引入一个充当def _get_page(self, *args, **kwargs): """ Returns an instance of a single page. This hook can be used by subclasses to use an alternative to the standard :cls:`Page` object. """ return Page(*args, **kwargs)构造函数的包装器的方法,我们可以猴子补丁构建页面。

例如,我们可以定义自己的speciale Page类:

Page

然后我们可以将 Page 文件添加到任何应用程序中,并写下:

Page

通常通过创建间接&#34;级别,允许用户在这些间接级别修复某些部分,因此可以将自己的实现注入Django部分。

子类化是最简单的修复,但本身不是唯一的修复。也许您想要预处理某些参数,或者对class SpecialPage(Page): # ... pass 对象进行后处理,或者发出一些&#34;信号&#34;对所有与创建的monkey_patching.py做某事的函数。也许对于一个页面来说,那些不是很符合逻辑的东西,但对于其他对象构造(比如模型实例),添加这些间接层次更有意义。