djangodjango-formsdjango-templates

access to pk in a template form


I want to display all elements of a form including the pk and I have not found a satisfying method to do so:

class SomeForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["number"] = forms.IntegerField(required = True)
        self.fields["id"] = forms.IntegerField(disabled = True)
        self.fields["data"] = forms.CharField(required = False)
        
    class Meta:
        model = SomeModel
        fields = ["id", "number", "data"]

So now I just call the form in the view with:

class SomeView(TemplateView):
    template_name = "app/sometemplate.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        obj = MODEL.objects.get(pk = context["pk"])
        MODEL_data = {}
        MODEL_data["number"] = obj.number
        MODEL_data["id"] = obj.pk
        MODEL_data["data"] = obj.data

        context["form"] = SomeForm(initial = MODEL_data)
        return context

and now in the templatetags I have a filter get_pk:

@register.filter(name='get_pk')
def get_pk(obj):
    return obj.initial["id"]

and I get the pk in the template with {{ form|get_pk }} and I feel like this is not smart. I tried stuff like {{ form.instance.id }} like suggested here. I still feel there must be an easy way to achieve this?


Solution

  • I don't know why you need form in template view? You just need to get the context no more.

    There are many comments in shared code like:

    1. Disabled id field in initial form

    2. Using different model name in form and get context data

    3. Filtering context by using context["pk"] before assessing obj

    Find the revised code,

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["obj"] = SomeModel.objects.get(pk = the desired value)
        return context
    

    Note: if you want user to insert pk then you can use input field inside form with get method and get its value inside get context data in this way:

    context["pk"] = self.request.GET.get("name of input field ")
    

    In template html you can display fields directly:

    {{obj.id}}, {{obj.name}}, {{obj.data}}