How to pass argument to form in updateview? - python

I want to use UpdateView in my model Event. This model had this field:
employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='event_employee')
My view :
class UpdateEvent(UpdateView):
model = Event
template_name = 'dashboard/pro_update_event.html'
form_class = UpdateEventForm
other_variable = None
def get_form_kwargs(self):
kwargs = super(UpdateEvent, self).get_form_kwargs()
names_clients = User.objects.filter(professionnels=self.request.user)
kwargs.update({'names_clients': names_clients})
return kwargs
def get_success_url(self, *args, **kwargs):
return reverse_lazy('pro_details_event', kwargs={'pk': self.object.pk})
My Form :
class UpdateEventForm(forms.ModelForm):
"""
edit an event
"""
class Meta():
model = Event
fields = ('employee', 'date_start', 'date_end')
def __init__(self, names_clients, *args, **kwargs):
super(UpdateEventForm, self).__init__(*args, **kwargs)
self.fields['employee'] = forms.ChoiceField(choices=tuple([(client.pk,client.last_name.capitalize()+" "+client.first_name.capitalize()) for client in names_clients]))
It seems work, the widget "select" contain the correct values.
example : <option value="2">Dupond Jean</option>
But when I submit the form :
Cannot assign "'2'": "Event.employee" must be a "User" instance.
I don't understand because if remove "get_form_kwargs" in my view and "def init" in my form, the value passed is the same (the pk of the employee). It's works with this way.
But the problem is all employee are selectable and the username is display not the firstname and lastname.

It's because the employee ForeignKey on your Event model points to the User model, but you're populating the choice field for the employee field with Particulier model data.
Either change the foreign key to point to the Particulier model, or pass in Users to the form kwargs

Sorry, I forgot to fix this error in the code in this page.
But I have the error in my 1st comment, with populating the choice field with an User model data.

Related

how can i save some information that i got in views to one of fields in models - django

this is my views.py :
i want save type in device field in model
class GetDeviceMixin( object):
def setup(self, request, *args, **kwargs):
super().setup( request, *args, **kwargs)
type= request.META['HTTP_USER_AGENT']
print(type)
return type
class RegisterView(GetDeviceMixin , generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy("register")
template_name = "man/man.html"
and this is my models.py
class account(AbstractBaseUser):
first_name= models.CharField(max_length=20,verbose_name="first name")
device = models.CharField(verbose_name="device" , max_length=100)
this is my forms.py:
class GetReq(forms.ModelForm):
class Meta:
model = account
fields = ['device',]
First, pop Classy CBVs onto your browser bookmark list ...
I'm assuming that you want to use a form, either to get other information from the user, or to allow the user to override the automatically determined value of device. In this case, you want to pass it as the initial value for device to the form
Now, look at CreateView to work out what to subclass. get_initial() looks hopeful, so
def get_initial(self):
initial = super().get_initial()
initial['device'] = self.device_type # as per the comment!
return initial
You should now see a form with the automatically determined value as the default value
If the intent was to get other fields of the model from the user and to always forcibly insert the automatically determined device_type, you would instead subclass form_valid
def form_valid(form):
obj = form.save( commit=False)
obj.device = self.device_type
obj.save()

Pass request.user parameter to modelformset_factory form

So I've a formset tied to a model and one of the fields in that is ForeignKey.
models.py
class Squad(models.Model):
rid = models.AutoField(primary_key=True)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
def __str__(self):
return self.team.tname
forms.py
class SquadForm(ModelForm):
class Meta:
model = Squad
def __init__(self, logged_user, user, *args, **kwargs):
super(SquadForm, self).__init__(*args, **kwargs)
self.fields['team'] = forms.ModelChoiceField(queryset=Team.rows.get_my_teams(user=logged_user), empty_label="None")
As you can see, the __init__ function is expecting an extra parameter logged_user which I'm hoping to pass via the views.py file. But if I do the following:
views.py
def choose_teams(request):
teamformset = modelformset_factory(Squad, extra=2, form=SquadForm(request.user))
form = teamformset(queryset=Squad.objects.none())
return render(request, 'foo.html', {'form':form})
I'm trying to pass the logged in user as a parameter on line 2 but this is resulting in the following message:
Field 'id' expected a number but got 'SquadForm'
Not sure what I'm missing here. But if I remove the parameter from line 2:
teamformset = modelformset_factory(Squad, extra=series.team_number, form=SquadForm)
it starts working (of course, I no longer expect the user in the forms.py file and remove it too) but shows all the data and not filtered one.
You can pass additional keyword arguments to your formset form by passing form_kwargs={} to your formset
class SquadForm(ModelForm):
class Meta:
model = Squad
def __init__(self, *args, logged_user, **kwargs):
super(SquadForm, self).__init__(*args, **kwargs)
self.fields['team'] = forms.ModelChoiceField(queryset=Team.rows.get_my_teams(user=logged_user), empty_label="None")
teamformset = modelformset_factory(Squad, extra=2, form=SquadForm)
form = teamformset(queryset=Squad.objects.none(), form_kwargs={'logged_user': request.user})

Set values for form field by query using filter

I want to set the item in dropdown using the query in the form. I want to add employee and the select company which using filter Is_Del= 0. I do not know how to set values for the drop down and where to write this query.
I tried to put in Forms.py, but it is not working.
This is form.py
class EmployeeCreateForm(forms.ModelForm):
class Meta:
model = Employee
fields = ('Emp_Name','Emp_company','Emp_Dept','Emp_Join_Date', 'Emp_End_Date')
def clean(self):
cleaned_data = super(EmployeeCreateForm, self).clean()
Emp_Name = cleaned_data.get('Emp_Name')
Emp_company = cleaned_data.get('Emp_company')
Emp_Dept = cleaned_data.get('Emp_Dept')
Emp_Join_Date = cleaned_data.get('Emp_Join_Date')
Emp_End_Date = cleaned_data.get('Emp_End_Date')
return cleaned_data
def __init__(self, *args, **kwargs):
super(EmployeeCreateForm,self).__init__(*args, **kwargs)
self.fields['Emp_company'].queryset = Company.objects.filter(Is_Del=0)
and below is my view.py
class EmployeeCraeteView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
model=Employee
form = EmployeeCreateForm
success_message = " Employee Craeted successfully!"
success_url="../../company/all-companies"
template_name = 'employee_form.html'
fields =[
'Emp_Name','Emp_company','Emp_Dept','Emp_Join_Date',
'Emp_End_Date'
]
companies= Company.objects.filter(Is_Del=0)
def form_valid(self,form):
form.instance.Emp_Crt_By = self.request.user
if form.cleaned_data['Emp_Join_Date'] >= form.cleaned_data['Emp_End_Date']:
form.add_error('Emp_End_Date', 'Joining date should be less than Ending date')
return self.form_invalid(form)
return super(EmployeeCraeteView, self).form_valid(form)
I want to show only this companies in the form which are filtered by Is_Del =0
Your EmployeeCreateView is wrong:
Remove the attributes form, fields and companies
Add form_class = EmployeeCreateForm.
The reason is that form doesn't do anything in a CreateView (see here). To use a custom form class, you need to pass it to form_class.
Your CreateView was dynamically creating the form using a modelform_factory with the fields you defined (if you hadn't added those you'd have seen your mistake immediately) and so your EmployeeCreateForm is never instantiated.

Exclude custom field in django admin form

I'm using django form to add custom field in my form, but I want to exclude this custom field in some condition(when user_id is set on url query param), how can I handle it?
Something interesting happens in my try and error, I put my custom field name in Mata.exclude of my form, but this custom field still generates in my form !!!!
Here is my code:
class PushTokenForm(forms.ModelForm):
push_scenario = forms.ChoiceField(
label=_('Push Scenario'),
choices=get_scenarios(),
)
class Meta:
model = PushToken
exclude = ['failed', 'push_scenario']
UPDATE
def get_form(self, request, obj=None, **kwargs):
self.exclude = []
user_id = request.GET['user_id'] if 'user_id' in request.GET else None
if user_id:
self.exclude.append('push_scenario')
form = super(PushTokenAdmin, self).get_form(request, obj, **kwargs)
return form

request.user as a choice in select widget in Django

I have a model field
is_anonymous = BooleanField(default=False)
I also have a ModelForm. I want this field to be represented with a select widget.
It would be
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['is_anonymous']
widgets = {
'is_anonymous': forms.NullBooleanSelect(),
}
It works. But I want the select widget to only have two choices true (1) and false (0) and the represented text in each option should be Anonymous for true and self.request.user for false.
I think I have to do this replacement in the views as self.request.user is not available in the ModelForm.
How can I do this?
It's not 100% clear what you want, but if you want to display a select dropdown with only two choices; "Anonymous" which maps to True and "myusername" (i.e. the username of the current user) which maps to False, you need to override the is_anonymous field's widget's choices attribute:
class MyModelForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
self.fields['is_anonymous'].widget = forms.Select(choices=[
(True, "Anonymous"),
(False, user.username)
])
class Meta:
model = MyModel
fields = ['is_anonymous']
because we need the user object in our form, we need to pass it manually as a parameter when defining the form in our view. This depends on the type of view you are using, but assuming it's a generic class based CreateView, you need the following:
class MyCreateView(CreateView):
form_class = MyModelForm
...
def get_form(self, form_class):
return self.form_class(self.request.user, **self.get_form_kwargs())
...

Categories

Resources