Home > Blockchain >  Django form not populating with POST data
Django form not populating with POST data

Time:02-03

I'm relatively new to Django so hopefully this is quite a simple issue. I am finding the debugging difficult and perhaps that is part of my problem here.

Problem: Django form seems to not be populating with post data.

Summary: I have 2 models Entities and Breaks. Breaks has a FK relationship to the entity_id (not the PK) on the Entities model.

I want to generate an empty form for all the fields of Breaks. Generating a basic form populates all the empty fields, but for the FK it generates a dropdown list of all PKs of the Entities table. This is not helpful so I have excluded this in the ModelForm below and tried to replace with a list of all the entity_ids of the Entities table. This form renders as expected.

class BreakForm(ModelForm):   
    class Meta:
        model = Breaks
        #fields = '__all__'
        exclude = ('entity',)
    
    def __init__(self, *args, **kwargs):        
        super(BreakForm, self).__init__(*args, **kwargs)         
        self.fields['entity_id'] = ModelChoiceField(queryset=Entities.objects.all().values_list('entity_id', flat=True))    

The below FormView is the cbv called by the URL. As the below stands if I populate the form, and for the FK column entity_id choose one of the values, the form will not submit. By that field on the form template the following message appears Select a valid choice. That choice is not one of the available choices.

class ContactFormView(FormView):
    template_name = "breaks/test/breaks_form.html"
    form_class = BreakForm

My initial thoughts were either that the datatype of this field (string/integer) was wrong or that Django needed the PK of the row in the Entities table (for whatever reason).

So I added a post function to the FormView and could see that the request.body was populating correctly. However I can't work out how to populate this into the ModelForm and save to the database, or overcome the issue mentioned above.

Addendum:

Models added below:

class Entity(models.Model):
    pk_securities = models.AutoField(primary_key=True)
    entity_id = models.CharField(unique=True)
    entity_description = models.CharField(blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'entities'
    
    
class Breaks(models.Model):
    pk_break = models.AutoField(primary_key=True)
    date = models.DateField(blank=True, null=True)    
    entity = models.ForeignKey(Entity, on_delete= models.CASCADE, to_field='entity_id')  
    commentary = models.CharField(blank=True, null=True)
    active = models.BooleanField()

    def get_absolute_url(self):
        return reverse(
            "item-update", args=[str(self.pk_break)]
        )

    def __str__(self):
        return f"{self.pk_break}"

    class Meta:
        managed = False
        db_table = 'breaks'

CodePudding user response:

In Django, the request object passed as parameter to your view has an attribute called "method" where the type of the request is set, and all data passed via POST can be accessed via the request. POST dictionary. The view will display the result of the login form posted through the loggedin. html.

CodePudding user response:

I think your problem is two fold, first is not rendering the dropdown correctly and second is form is not saving. For first problem, you do not need to do any changes in ModelChoiceField queryset, instead, add to_field_name:

class BreakForm(ModelForm):   
    class Meta:
        model = Breaks
        #fields = '__all__'
    
    def __init__(self, *args, **kwargs):        
        super(BreakForm, self).__init__(*args, **kwargs)         
        self.fields['entity_id'] = ModelChoiceField(queryset=Entities.objects.all(), to_field_name='entity_id')

Secondly, if you want to save the form, instead of FormView, use CreateView:

class ContactFormView(CreateView):
    template_name = "breaks/test/breaks_form.html"
    form_class = BreakForm
    model = Breaks
  • Related