as_crispy_field got passed an invalid or inexistent field

I have an UpdateView which has extra context, ‘webrem’, added through a get_context_data() override. The problem that I have is that when I add a ‘|as_crispy_field’ tag to any of the extra context fields I get the above error.

I suspect that I need to give crispy some information about extra context fields, so that it can render them correctly, but I don’t know how. I have tried via ini but without success.

FYI the extra content is a one to one model with Webinar (the UpdateView model) as it’s primary key.

View

class WebinarUpdateView(UpdateView):
    model = Webinar
    form_class = WebinarAddForm
    template_name = 'webinar/webinar-add-update.html'
    extra_context = {'page_title': 'Edit Webinar'}

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if self.object:
            context['webrem'] = WebinarReminder.objects.filter(webinar=self.object).first()

(the rest of the model omitted as is irrelevant)

Form

class WebinarAddForm(forms.ModelForm):
    HOURS = "HR"
    MINUTES = "MIN"
    CHOICES_INTERVAL = [
        (HOURS, 'hour(s) before'),
        (MINUTES,'minute(s) before' ),
    ]

    webinarpresenters = forms.ModelMultipleChoiceField(queryset=None)
    notifications_unit_1 = forms.ChoiceField(widget=forms.Select(attrs={'class': 'btn-light notifications_unit custom-select'}),
                                             label='',
                                             choices=CHOICES_INTERVAL,
                                             initial='MIN',
                                             required=False)
    notifications_interval_1 = forms.CharField(label='', max_length=2, required=False)
    notifications_unit_2 = forms.ChoiceField(widget=forms.Select(attrs={'class': 'btn-light notifications_unit custom-select'}),
                                             label='',
                                             choices=CHOICES_INTERVAL,
                                             initial='HR',
                                             required=False)

    notifications_interval_2 = forms.CharField(label='',
                                               max_length=2,
                                               required=False)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["webinarpresenters"].queryset = WebinarPresenter.objects.filter(is_active=True)

    class Meta:
        model = Webinar
        fields = ('title',
                  'description',
                  'webinar_event_link',
                  'webinarpresenters',
                  'notifications_unit_1',
                  'notifications_interval_1',
                  'notifications_unit_2',
                  'notifications_interval_2'
                  )

Models

class Webinar(models.Model):
    title = models.CharField(max_length=100, blank=False, null=False)
    description = models.TextField(blank=False, null=False)
    webinar_event_link = models.URLField(default="https://zoom.com", blank=False, null=True)
    webinarpresenters = models.ManyToManyField('WebinarPresenter', through='WebinarPresenting')


class WebinarReminder(models.Model):

    notifications_unit_1 = models.CharField('', max_length=3, blank=True, null=True)
    notifications_interval_1 = models.IntegerField(blank=True, null=True)
    notifications_unit_2 = models.CharField('', max_length=3, blank=True, null=True)
    notifications_interval_2 = models.IntegerField(blank=True, null=True)
    notification_time_2 = models.DateTimeField(blank=True, null=True)
    webinar = models.OneToOneField(Webinar, on_delete=models.CASCADE, primary_key=True)

The problem fields are:

‘notifications_unit_1’,
‘notifications_interval_1’,
‘notifications_unit_2’,
‘notifications_interval_2’

Traceback

[2023-06-25 08:02:44,995] ERROR: Internal Server Error: /webinar/webinar-add
Traceback (most recent call last):
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 204, in _get_response
    response = response.render()
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 170, in render
    return self._render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 988, in render
    output = self.filter_expression.resolve(context)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/django/template/base.py", line 698, in resolve
    new_obj = func(obj, *arg_vals)
  File "/Users/pj/Documents/dev/BACKOFFICE/venv/lib/python3.9/site-packages/crispy_forms/templatetags/crispy_forms_filters.py", line 99, in as_crispy_field
    raise CrispyError("|as_crispy_field got passed an invalid or inexistent field")

You’re showing the view but not the model. Please include the model in your post.

The filter as_crispy_field is a filter for a field in a form. Your webrem context entry is an instance of a Model and is not a form field.

Also, for future reference, when you’re asking for assistance regarding an error you are receiving, please post the entire error, including the traceback.

Hi Ken,

You are quite right, I’ve edited the original post - thank you.

So, is there any workaround for this, so that ‘crispy’ treats it like a form and renders accordingly?

It’s not really clear to me what you’re trying to do here.

Crispy is designed to format forms, not instances of objects. You can create a form for that object and use crispy for it, but I’m not sure that’s what you’re looking for.

It probably would help if you posted the models involved.

Thank you Ken,

What I am trying to do is use UpdateView to manage two separate but connected models (the second model ‘WebinarReminder’ has a one to one relationship with Webinar).

I’ll update my post to include the models.

Thanks again.

Ok, that clears up a lot.

Personal recommendation - either use an FBV or create your own version of a CBV based upon the View class. The Django-provided CBVs are not really designed to work with multiple models. (Yes, you can get them to work, but it has always felt awkward to me.)

For a “link of links”, see my post at Multiple Models to one Form - #2 by KenWhitesell

In your situation here, I’d consider creating two model forms (with prefixes), one for each model. It’s probably going to be about as easy as any other method.

Thank you Ken,

I wasn’t aware that it was possible to integrate two model forms into the same template.

Could I trouble you for a simple example?

It’s very easy to integrate two model forms in the same template. The issues are working with two model forms in the same Django-provided edit CBV. (The referenced links get into the details associated with that.)