Instance of djaform not updating - django

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'
)

Related

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)

'ProjectFormFormSet' object has no attribute 'request'

I want to add to my project one feature that only authenticated users can have access their stuff. But when I write queryset it throws an error like ModelNameFormSet object has no request attribute
views.py
class BaseAuthorFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.queryset = Project.objects.filter(author_id=self.request.user.pk)
def add_object(request):
ProjectFormSet = modelformset_factory(Project, formset=BaseAuthorFormSet, fields=( 'service_name', 'service_code', 'report_month', 'report_year', 'last_year'), extra=1)
if request.method == "POST":
form = ProjectFormSet(request.POST)
form.author = request.user
if form.is_valid():
form.save()
form = ProjectFormSet()
return render(request, 'app1/home.html',{'form':form})
I have only this code. How can I solve this issue? Thank you beforehand!
If you need the request in the formset, you need to pass it there. Also note that adding the author to the formset won't do anything, you need to add it to the result of each form save.
class BaseAuthorFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
self.queryset = Project.objects.filter(author_id=self.request.user.pk)
def add_object(request):
ProjectFormSet = modelformset_factory(Project, formset=BaseAuthorFormSet, fields=( 'service_name', 'service_code', 'report_month', 'report_year', 'last_year'), extra=1)
if request.method == "POST":
formset = ProjectFormSet(request.POST, request=request)
if formset.is_valid():
for form in formset:
obj=form.save(commit=False)
obj.author = request.user
obj.save()
return redirect('somewhere')
form = ProjectFormSet(request=request)
return render(request, 'app1/home.html',{'form':form})

create help text for a field dynamically

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.

How to write an update view with formset_factory

I love how I can pass an instance to a form and it will populate it on a page. The trouble I am having is with formset_factory. I am trying to use query_set...
def classroom_update(request, pk):
classroom = get_object_or_404(Classroom, pk=pk)
students = classroom.student_set.all()
# Empty formset forms should be required
class RequiredFormSet(BaseFormSet):
def __init__(self, *args, **kwargs):
super(RequiredFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.empty_permitted = False
#StudentFormSet = inlineformset_factory(Classroom, Student)
StudentFormSet = formset_factory(StudentForm, max_num=100, formset=RequiredFormSet)
if request.method == 'POST': # If the form has been submitted...
classroom_form = ClassroomForm(request.POST)
student_formset = StudentFormSet(request.POST, request.FILES)
if classroom_form.is_valid() and student_formset.is_valid():
classroom = classroom_form.save(commit=False)
classroom.user = request.user
classroom.save()
for form in student_formset.forms:
student = form.save(commit=False)
student.classroom = classroom
student.save()
return HttpResponseRedirect('/') # Redirect to a 'success' page
else:
classroom_form = ClassroomForm(instance=classroom)
student_formset = StudentFormSet(query_set=students)
# For CSRF protection
# See http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
c = {'classroom_form': classroom_form,
'student_formset': student_formset,
}
c.update(csrf(request))
return render_to_response('reports/modify_classroom.html', c)
EDIT: Here is the error message...
formset_factory() got an unexpected keyword argument 'query_set'
Apparently I don't know how to use query_set...

data not storing in database django

My first issue is data is not going in database.it is not showing any error but not storing as well.
and my second issue is that i am pre-populating the form field with query set in a drop-down but it is showing me the id(primary key) and i want show some other field.how can i do this?
my view
def payment(request):
#form = jobpostForm_first()
#country_list = Country.objects.all()
if request.POST:
form = jobpostForm_detail(request.POST)
if form.is_valid():
if '_Submit' in request.POST:
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = jobpostForm_detail()
#form.fields['country'].queryset = Country.objects.all()
c = {}
c.update(csrf(request))
return render_to_response('portal/display.html',{
'form':form
},context_instance=RequestContext(request))
my modelform:
class jobpostForm_detail(ModelForm):
class Meta:
model = payment_detail
fields = ('payment_type','country')
def __init__(self, *args, **kwargs):
super(jobpostForm_detail, self).__init__(*args, **kwargs)
self.fields['country'].queryset = Country.objects.all()
self.fields['payment_type'].queryset = Payment_types.objects.all()
self.helper = FormHelper()
self.helper.form_class = 'horizontal-form'
self.helper.form_id = 'id-jobpostform'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit_addcontent', 'Pay'))
super(jobpostForm_detail, self).__init__(*args, **kwargs)
My template:
<form method="post" action="/portal/next/post/" class="blueForms" id="id-jobpostform">
{% csrf_token %}
{% crispy form %}
</form>
Why are you checking for "_Submit" in your view?
I suggest you read how to use a form in a view, especially the comments:
...
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
...
In your case, you just need to call form.save() after form.is_valid()
Question for you: can you please explain this bit of code in your form class? typo, I suppose?
widgets = {
}),
}