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) # ← 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
Related
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'
)
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)
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.
I am trying to use an UpdateView in Django to update two forms simultaneously. I have the get method working properly, but when I submit the update, the post method creates a new instance of the forms. How can I grab the forms from the get method and update them without creating a new instance? Everything is redirecting fine and I am getting no errors.
class MotionStudyInstanceUpdateView(UpdateView):
model = MotionStudyInstance
fields = ['height', 'weight', 'skin_type_score', 'fitzpatrick_skin_type']
template_name = 'data/motionstudyinstance_update.html'
success_url = reverse_lazy('data:motion-studies')
def get_context_data(self, **kwargs):
pass
def get(self, request, **kwargs):
pk = self.kwargs['pk']
item = MotionStudyInstance.objects.get(id=pk)
general_info = item.general_info
form = MotionStudyInstanceForm(
initial={'height': item.height, 'weight': item.weight, 'skin_type_score': item.skin_type_score,
'fitzpatrick_skin_type': item.fitzpatrick_skin_type})
form_two = GeneralInfoForm(initial={'case_report_form_number': general_info.case_report_form_number,
'form_type': general_info.form_type,
'study_start_date': general_info.study_start_date,
'signed_consent': general_info.signed_consent,
'gender': general_info.gender,
'miscellaneous_notes': general_info.miscellaneous_notes,
'adverse_events': general_info.adverse_events})
return render(request, self.template_name, {'form': form, 'foreign_form': form_two})
def post(self, request, **kwargs):
if request.method == 'POST':
form = MotionStudyInstanceForm(request.POST)
foreign_form = GeneralInfoForm(request.POST)
if form.is_valid() and foreign_form.is_valid():
general_info = foreign_form.save()
user_form = form.save(commit=False)
user_form.general_info = general_info
user_form.save()
return redirect('data:motion-studies')
else:
form = MotionStudyInstanceForm()
return render(request, self.template_name, {'form': form})
forms.py
class MotionStudyInstanceForm(forms.ModelForm):
class Meta:
model = MotionStudyInstance
exclude = ('general_info',)
widgets = {
'validation_status': forms.HiddenInput(),
'author': forms.HiddenInput(),
'sibling': forms.HiddenInput()
}
class GeneralInfoForm(forms.ModelForm):
class Meta:
model = GeneralInfo
fields = '__all__'
widgets = {
'form_type': forms.HiddenInput(),
}
Looks like you should be using the instance parameter on the forms.
So you can update it on the post, and display it on the get
something like this:
def post(self, request, **kwargs):
pk = self.kwargs['pk']
item = MotionStudyInstance.objects.get(id=pk)
if request.method == 'POST':
form = MotionStudyInstanceForm(request.POST, instance=item)
Consider this simple user profile:
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
onboarding_step = models.SmallIntegerField(default='1')
What is the simplest method it increment the onboarding_step within UserProfile each time a separate form from a different model is submitted? For example:
Here's the ModelForm (from a separate model, Site) I am submitting:
class OnBoardingProgressForm(forms.ModelForm):
class Meta:
model = Site
fields = ( 'abc', 'xyz', )
And here is the view.py for the form:
if request.method == "POST":
form = OnBoardingProgressForm( request.POST )
if form.is_valid():
....
THIS CODE DOES NOT WORK BUT IS MY BEST GUESS:
last = request.user.profile
last.onboarding_step = 2
....
obj = form.save(commit=False)
obj.user = current_user
obj.save()
return render(request, "nextpage.html", {'form': form })
How can I increment the user.onboarding_step by 1?
if request.method == "POST":
form = OnBoardingProgress( request.POST )
if form.is_valid():
....
// Can I increment the code here? //
....
obj = form.save(commit=False)
obj.user = current_user
obj.save()
user_obj = UserProfile.objects.get(user=request.user)
user_obj.onboarding_step = user_obj.onboarding_step + 1
user_obj.save()
return render(request, "nextpage.html", {'form': form })
or you can make autoincrement field also.
Get the UserProfile object for the current user and then increment the value of the attribute of onboarding_step.
Try this:
if request.method == "POST":
form = OnBoardingProgress(request.POST)
current_user = request.user
if form.is_valid():
user_profile = UserProfile.objects.filter(user=current_user)[0] # get the user profile object for the current user
user_profile.onboarding_step += 1 # increment the value
user_profile.save() # save the object
obj = form.save(commit=False)
obj.user = current_user
obj.save()
return render(request, "nextpage.html", {'form': form })