create help text for a field dynamically - django

I have my response form and view like this
class ResponseForm(ModelForm):
class Meta:
model = ResponseModel
exclude = ('author', 'title','submit_count')
# help_texts = {
# 'ans1': user.q1.value,
# }
#login_required
def ResponseFormView(request):
if request.method == "POST":
form = ResponseForm(request.POST)
if form.is_valid():
submission = form.save(commit=False)
submission.author = request.user
submission.save()
return render(request, 'thanks.html', {})
else:
form = ResponseForm()
return render(request, 'response_tem.html', {'form': form})
I want the help text for 'ans1' field to be the value of q1 field of request.user. How do I do it?

You can do it like this:
class ResponseForm(ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None) # popping user from known arguments
super(ResponseForm, self).__init__(*args, **kwargs)
if user:
self.fields['ans1'].help_text = "Help Text for {}".format(user.username)
class Meta:
model = ResponseModel
exclude = ('author', 'title','submit_count')
#login_required
def ResponseFormView(request):
if request.method == "POST":
form = ResponseForm(request.POST)
if form.is_valid():
submission = form.save(commit=False)
submission.author = request.user
submission.save()
return render(request, 'thanks.html', {})
else:
form = ResponseForm(user=request.user) # passing user as known argument
return render(request, 'response_tem.html', {'form': form})
Here, in the view I am passing the request.user as known argument when I am initiating Form Class's Object (marked with comment). Then in the Form, I am catching the user sent from view and updating the field's help text.

Related

Instance of djaform not updating

I have the next form in Django:
class Medical(forms.ModelForm):
worker= forms.ModelChoiceField(
queryset=Worker.objects.none(),
empty_label=None,
widget=forms.Select(attrs={'class': 'form-control'})
)
description=forms.CharField(
widget=forms.Textarea(attrs={'class': 'form-control'})
)
upload=forms.FileField(
widget=forms.FileInput(attrs={'class': 'form-control'})
)
class Meta:
model = Medical_Issue
fields = (
'worker',
'description',
'upload',
)
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id')
method=kwargs.pop('method')
super().__init__(*args, **kwargs)
self.fields['worker'].queryset = Worker.objects.filter(user_id=user_id)
def save(self, commit=True):
m = super(Medical, self).save(commit=False)
m.worker=self.cleaned_data['worker']
m.description=self.cleaned_data['description']
m.upload=self.cleaned_data['upload']
if commit:
m.save()
return m
And following views:
def medical_list(request):
worker=Worker.objects.filter(user_id=request.user.id).get()
issues=Medical_Issue.objects.filter(worker=worker.id).order_by('-created_at')
return render(request,'medical_list.html', {'medical_issues':issues})
def medical_add(request):
print(request.user.id)
if request.method == "POST":
form = Medical(request.POST,request.FILES,user_id=request.user, method= 'ADD')
if form.is_valid():
form.save()
return redirect('medical_list')
else:
form = Medical(user_id=request.user, method= 'ADD')
return render(request, 'medical_add.html', {'method':'ADD','form': form})
def medical_edit(request,id_issue):
worker=Worker.objects.get(user_id=request.user)
issues=Medical_Issue.objects.filter(worker=worker).order_by('-created_at')
issue= Medical_Issue.objects.get(id=id_issue)
if request.method == 'GET':
form = Medical(user_id=worker.user_id,instance=issue, method= 'EDIT')
else:
form = Medical(request.POST, request.FILES, user_id=worker.user_id, method= 'EDIT')
if form.is_valid():
form.save()
return redirect('medical_list')
return render(request,'medical_add.html', {'method':'EDIT','form': form})
Main probles is when adding, it saves record just fine, but when editing, it is creating a new instance of the issue.
I´m trying to make it modifying save method on form, but maybe it´s not the right approach? With thata said, I have tried to add an id field to the form, but same results from this
Thanks
I suspect that you don't pass the correct instance value to the form in your medical_edit view:
issue= Medical_Issue.objects.get(id=id_issue)
if request.method == 'GET':
form = Medical(
user_id=worker.user_id,
instance=issue, # <-- issue or parte?
method='EDIT'
)
UPDATE
It should also include the instance argument in the POST method.
if request.method == 'GET':
# ...
else:
form = Medical(
request.POST,
request.FILES,
instance=issue, # <--
user_id=worker.user_id,
method= 'EDIT'
)

adding initial value to Django model form

I just want to add an initial value to one field when it gets populated, this is my view
def add_program(request):
module = Module.objects.all()
last_item = Programme.objects.filter(module_id__in=module).last()
if last_item:
day = last_item.day + 1
else:
day = 1
initial_data = {
'day': day
}
if request.method == 'POST':
form = ProgramAddForm(request.POST or None, request.FILES or None, initial=initial_data)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
return redirect('program_add')
else:
form = ProgramAddForm()
return render(request, 'client_apps/program/form.html', {'form': form})
and form
class ProgramAddForm(forms.ModelForm):
class Meta:
model = Programme
fields = ['module', 'day', .........]
even though initial value is passed nothing is visible in day field when form populates, is there any alternative method?
That is because you only use it in case of the POST request, not the GET request:
def add_program(request):
module = Module.objects.all()
last_item = Programme.objects.filter(module_id__in=module).last()
if last_item:
day = last_item.day + 1
else:
day = 1
initial_data = {
'day': day
}
if request.method == 'POST':
form = ProgramAddForm(request.POST, request.FILES, initial=initial_data)
if form.is_valid():
instance = form.save()
return redirect('program_add')
else:
form = ProgramAddForm(initial=initial_data) # &leftarrow; initial data for a GET request
return render(request, 'client_apps/program/form.html', {'form': form})
you can add it in the init method
class ProgramAddForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(YoutubeModelForm, self).__init__(*args, **kwargs)
self.fields["day"].value = "day"
self.fields["day"].initial = "day"
self.fields["day"].initial = "padding-top: 0;"
class Meta:
model = Programme
this to load in the form and in the admin of django

Django Form : after correctly submitting form I got this: "this field is required"

I've a category and I've added a form for user in each category.
So I've two fields to fill and after filling them correctly I submit but the page reload, and nothing appears in my DB... only one error on Image field: This field required. I don't really know what's wrong here.
class Picture(models.Model):
catego = models.ForeignKey(Catego,on_delete=models.CASCADE,related_name="catego_pictures")
user = models.ForeignKey(User, blank=True, null=True,on_delete=models.CASCADE,related_name='user_pictures')
image = models.ImageField(upload_to='nutriscore/')
pictureoption = models.CharField(max_length=20,choices=Pictureoption.choices,default=Pictureoption.HOME,)
publishing_date = models.DateField(auto_now_add=True)
class CreatePictureForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super(CreatePictureForm, self).__init__(*args,**kwargs)
self.helper = FormHelper()
self.helper.form_method="post"
self.helper.layout = Layout(
Field("image",css_class="single-input"),
Field("pictureoption",css_class="single-input"),
)
self.helper.add_input(Submit('submit','Upload a pic',css_class="single-input textinput textInput form-control"))
class Meta:
model = Picture
fields = [
'image',
'pictureoption',
]
def __str__(self):
return self.catego.name
views.py
#login_required(login_url='/cooker/login')
def catego(request, slug):
catego = Catego.objects.get(slug=slug)
context = {
'catego': catego
}
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CreatePictureForm(request.POST)
# check whether it's valid:
if form.is_valid():
form.instance.catego = self.object
form.instance.user = self.request.user
form.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
form = CreatePictureForm()
context['form'] = form # add `form` to the context
return render(request, 'post_catego.html', context)
here is the answer
#login_required(login_url='/cooker/login')
def catego(request, slug):
catego = Catego.objects.get(slug=slug)
context = {
'catego': catego
}
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CreatePictureForm(request.POST, request.FILES)
# check whether it's valid:
if form.is_valid():
form.instance.catego = catego
form.instance.user = request.user
form.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
form = CreatePictureForm()
context['form'] = form # add `form` to the context
return render(request, 'post_catego.html', context)

Initialize form with request.user in a ModelForm django

I have this ModelForm
class ScheduleForm(forms.ModelForm):
class Meta:
model = Schedule
fields = ['name', 'involved_people',]
def __init__(self, user, *args, **kwargs):
super(ScheduleForm, self).__init__(*args, **kwargs)
self.fields['involved_people'].queryset = Profile.objects.exclude(user=user)
This is my view
def create_schedule(request):
form = ScheduleForm(request.POST or None)
schedules = Schedule.objects.all().order_by('deadline_date')
if form.is_valid():
schedule = form.save(commit=False)
schedule.save()
messages.success(request, "Schedule added successfully!")
return render(request, 'schedule/index.html', {'schedules': schedules})
context = {'form': form}
return render(request, 'schedule/create_schedule.html', context)
How do you pass request.user in the view?
How do you initialize the form with request.user in it?
You have added user to the __init__ method,
def __init__(self, user, *args, **kwargs):
so now you just pass the user as the first argument when you instantiate your form.
form = ScheduleForm(request.user, request.POST or None)

KeyError in Django form kwargs

def user_info(request, template_name='social/retrieve_user_data.html', username=None):
user = User.objects.get(username=username)
if request.method == 'POST':
form = UserInfoForm(request.POST, user)
print(form.is_valid())
if form.is_valid():
form.save()
else:
print('not post')
form = UserInfoForm(user)
return render_to_response(template_name, RequestContext(request, {
'form': form,
}))
class UserInfoForm(forms.Form):
def __init__(self,*args,**kwargs):
self.user = kwargs.pop('user')
super(UserInfoForm,self).__init__(*args,**kwargs)
This is producing a KeyError with exception value u'user'. What is wrong here? In both cases, form is initialized with a valid value of user. Why am I getting a keyerror>
You're not passing the user as a keyword argument in either the if or the else block. It should be:
form = UserInfoForm(request.POST, user=user)
and:
form = UserInfoForm(user=user)
Only func(foo=bar)can put {"foo":bar} into kwargs dictionary! According to your code form = UserInfoForm(request.POST, user),you can use self.user = args[1] to capture user.