finethen
finethen

Reputation: 433

Django: How to save predefined values in modelForm

Good evening,

is it possible to change the ModelForm inside my forms.py, so that already known values are saved inside the database? For example:

models.py:

class Customer(models.Model):
    name = models.CharField(max_length=255)

class Project(models.Model):
    customer = models.ForeignKey(Customer, null=False, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)

class Entry(models.Model):
    user = ...request.user.id?...
    customer = models.ForeignKey(Customer, null=False, on_delete=models.CASCADE)
    project= models.ForeignKey(Project, null=False, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)

forms.py:

class EntryForm(ModelForm):
    class Meta:
        model = Entry
        fields = '__all__'

    def __init__(self, *args, pk, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['project'].queryset = Project.objects.filter(customer_id=pk)

When entering the knew site, I already know about the only possible Customer (pk)! I don't want to place a choicefield inside my knew site, but the customer should be saved inside my database nonetheless! Same goes for the active user (request.user), respectively the id (request.user.id). Can this data be passed into the modelForm as well?

Did someone else also had this problem and might know the solution? What do I have to change inside my modelForm to make it work?

Thanks for all your efforts and a happy weekend to all of you!

Upvotes: 1

Views: 249

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476614

You don't have to. You can simply exclude the customer field from the fields:

class EntryForm(ModelForm):
    class Meta:
        model = Entry
        exclude = ['customer']

    def __init__(self, *args, pk, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['project'].queryset = Project.objects.filter(customer_id=pk)

Then in the view where you use the EntryForm, you can thus implement this as:

def my_view(request, customer_id):
    if request.method == 'POST':
        form = EntryForm(request.POST, request.FILES, pk=customer_id)
        if form.is_valid():
            form.instance.customer_id = customer_id
            form.save()
            return redirect('name-of-some-view')
    else:
        form = EntryForm(pk=customer_id)
    return render(request, 'name_of_template.html', {'form': form})

You thus can "inject" data, by setting it at form.instance.

Upvotes: 1

Related Questions