Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selecting layout objects with slices doesn't work ('LayoutSlice' object is not subscriptable) #1326

Closed
Sulfyderz opened this issue Jan 2, 2023 · 4 comments

Comments

@Sulfyderz
Copy link

Sulfyderz commented Jan 2, 2023

  • Package version: 1.14.0
  • Django version: 4.1.3
  • Python version: 3.10.4
  • Template pack: bootstrap5

Description:

Hello,

There is a bug with the helper when we want to update the layout on the go.
I have this layout in my form __init__ method:

self.helper.layout = Layout(
            Div(
                Div(
                    HTML('<ul id="ul-id-member">'),
                    HTML("</ul>"),
                    BaseInput(
                        "input-member",
                        "",
                        css_id="input-id-member",
                        hx_include="#ul-id-member",
                        hx_target="#member-suggestions",
                        hx_trigger="focus changed, newMemberSearch from:body delay:200ms",
                        hx_swap="innerHTML",
                        hx_get="",
                    ),
                    css_class="member-tag",
                ),
                HTML('<ol id="member-suggestions" class="member-suggestions"></ol>'),
                css_class="member-invite",
            ),
            Field("role", id="select-id-role"),
            Submit("invite", "Invite"),
            Button("cancel", "Cancel"),
        )

I would like to access the BaseInput as described in the doc. Unfortunately, it doesn't work at all. When I try form.helper[0][0][-1] in my view, Python tells me that TypeError: 'LayoutSlice' object is not subscriptable.

Not sure, but I think it's a bug. Could you help me ?

@smithdc1
Copy link
Member

I think it's the [-1] that's not supported. Does [0][1] work for you?

@Sulfyderz
Copy link
Author

Sulfyderz commented Feb 15, 2023

Hello,

No, it doesn't work.
I tried these :

>>> form.helper[0][0] # Should select the nested Div
>>> form.helper[0][1]  # Should select the nested HTML

Then I got this :

Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: 'LayoutSlice' object is not subscriptable

If I use form.helper.layout[0][0][1] instead of form.helper[0][0][-1] to select my BaseInput, it works but it's not a LayoutSlice object. Thus, I don't have the update_attributes method. If I use form.helper[1] however, I do have that method. It seems form.helper only works for non nested objects (e.g. form.helper[0] works, I do have a LayoutSlice object). Could you help?

@Sulfyderz Sulfyderz reopened this Feb 15, 2023
@Sulfyderz
Copy link
Author

Sulfyderz commented Feb 15, 2023

Well, I found something interesting. It's somehow related to my other issue #1327. Since I can't have any LayoutSlice for nested objects, I can't have the related methods such as update_attributes.

What could be great is not to have that question in mind: "Should I use form.helper[0] or form.helper.layout[0] ?". Both should have the same methods. What do you think @smithdc1 ?

@Sulfyderz
Copy link
Author

Sulfyderz commented Feb 16, 2023

Hello again,

After checking your code, I know why it doesn't work. Your LayoutSlice doesn't have a __getitem__ method. That's why you can only have first-level layout elements with LayoutSlice. Moreover, you are right about -1 as an indice, form.helper[-1].update_attributes do not work at all.

I tried to change/update your code to PR but I didn't get your interest with the slice as follow :

class LayoutSlice:
    # List of layout objects that need args passed first before fields
    args_first = (Fieldset, MultiField, Container)

    def __init__(self, layout, key):
        self.layout = layout
        if isinstance(key, int):
            self.slice = slice(key, key + 1, 1)
        else:
            self.slice = key

Almost all other methods in your LayoutSlice use that. A simpler way is to remove it. If you can share your agenda to have chosen that way, I could help.

@Sulfyderz Sulfyderz closed this as not planned Won't fix, can't repro, duplicate, stale Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants