Related
I have a specific problem with my forms. I think it would be better to share my codes instead of explaining the problem in detail.
However, to explain in a nutshell; inside my model I have field OneToOneField and model of that field has inlineformset_factory form. My new model also has a form and I want to save both forms.
I get the following error when I want to save the offer update form:
TypeError at /ru/mytarget/offer-update/T2GTTT053E9/
AdminOfferUpdateView.form_invalid() missing 2 required positional arguments: 'request_form' and 'request_item_formset'
Models:
request.py
class RequestModel(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name="customer_requests")
id = ShortUUIDField(primary_key=True, length=10, max_length=10, prefix="T", alphabet="ARGET0123456789", unique=True, editable=False)
status = models.BooleanField(default=True)
request_title = models.CharField(max_length=300)
......
updated_on = models.DateTimeField(auto_now=True)
published_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return str(self.request_title)
class Meta:
verbose_name_plural = "Requests"
verbose_name = "Request"
def get_absolute_url(self):
return reverse('mytarget:customer_request_details', kwargs={'pk': self.id})
class RequestItem(models.Model):
request_model = models.ForeignKey(RequestModel, on_delete=models.CASCADE, related_name="request_items")
product_name = models.CharField(max_length=300)
......
offer.py
class OfferModel(models.Model):
request_model_name = models.OneToOneField(RequestModel, on_delete=models.CASCADE, primary_key=True)
status = models.BooleanField(default=True)
offer_validity = models.CharField(max_length=50, blank=True)
......
updated_on = models.DateTimeField(auto_now=True)
published_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return str(self.request_model_name)
class Meta:
verbose_name_plural = "Offers"
verbose_name = "Offer"
def get_absolute_url(self):
return reverse('mytarget:admin_offer_update', kwargs={'pk': self.request_model_name})
Forms:
request_create_form.py
class CustomerRequestForm(forms.ModelForm):
disabled_fields = ("customer",)
class Meta:
model = RequestModel
fields = ("customer", "request_title", "delivery_time", "shipping_country", "shipping_address",
"preferred_currency", "shipping_term", "delivery_term")
widgets = {
'request_title': TextInput(attrs={'class': 'form-control tableFormInputs',
'placeholder': _('Example: Printers, Toner, and Cartridges')}),
......
}
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('customer')
super(CustomerRequestForm, self).__init__(*args, **kwargs)
self.fields['preferred_currency'].queryset = self.fields['preferred_currency'].queryset.translated().order_by("translations__currency_name")
self.fields['shipping_term'].queryset = self.fields['shipping_term'].queryset.translated().order_by("translations__shipping_term")
for field in self.disabled_fields:
self.fields[field].widget = forms.HiddenInput()
self.fields[field].disabled = True
class CustomerRequestItemForm(forms.ModelForm):
class Meta:
model = RequestItem
fields = ("product_name", "product_info", "target_price", "price", "quantity", "dimensions", "net_weight", "gross_weight",
"hs_or_tn_ved_code", "brand", "manufacturer", "origin_country", "manufacturer_address")
exclude = ()
widgets = {
'product_name': TextInput(attrs={'class': 'form-control tableFormInputs'}),
......
}
RequestItemInlineFormset = inlineformset_factory(RequestModel, RequestItem,
form=CustomerRequestItemForm,
extra=1,
can_delete=True
)
offer_update_form.py
class AdminOfferUpdateForm(forms.ModelForm):
disabled_fields = ()
hidden_fields = ("request_model_name",)
request_title = forms.CharField(required=False, widget=TextInput(attrs={'class': 'form-control tableFormInputs', 'placeholder': _('Example: Printers, Toner, and Cartridges')}))
......
class Meta:
model = OfferModel
fields = ("request_model_name", "offer_validity", ......
)
widgets = {'offer_validity': TextInput(attrs={'class': 'form-control tableFormInputs'}),
......
'is_detailed_offer': CheckboxInput(attrs={'class': 'form-check-input'}),
}
def __init__(self, *args, **kwargs):
super(AdminOfferUpdateForm, self).__init__(*args, **kwargs)
self.fields["preferred_currency"].choices = [(c.id, c.currency_name) for c in Currency.objects.all()]
self.fields["shipping_term"].choices = [(st.id, st.shipping_term) for st in ShippingTerm.objects.all()]
self.fields["delivery_term"].choices = [(dt.id, dt.delivery_term) for dt in DeliveryTerms.objects.all()]
self.fields["request_statuses"].choices = [(r.id, r.status) for r in RequestStatus.objects.all()]
for field in self.disabled_fields:
self.fields[field].disabled = True
for field in self.hidden_fields:
self.fields[field].widget = forms.HiddenInput()
Views:
offer_update_view.py
#method_decorator([login_required(login_url=reverse_lazy("accounts:signin")), user_is_superuser], name='dispatch')
class AdminOfferUpdateView(UpdateView):
model = OfferModel
form_class = AdminOfferUpdateForm
template_name = "mytarget/admin_offer_update.html"
def get_context_data(self, **kwargs):
context = super(AdminOfferUpdateView, self).get_context_data(**kwargs)
if self.request.POST:
context['request_form'] = AdminOfferUpdateForm(self.request.POST, instance=self.object.request_model_name)
context['request_item_formset'] = RequestItemInlineFormset(self.request.POST, instance=self.object.request_model_name)
else:
context['request_form'] = AdminOfferUpdateForm(instance=self.object.request_model_name)
context['request_item_formset'] = RequestItemInlineFormset(instance=self.object.request_model_name)
return context
def form_valid(self, form):
context = self.get_context_data()
request_form = context['request_form']
request_item_formset = context['request_item_formset']
with transaction.atomic():
self.object = form.save()
if request_form.is_valid() and request_item_formset.is_valid():
request_form.instance = self.object.request_model_name
request_form.save()
request_item_formset.instance = self.object.request_model_name
request_item_formset.save(commit=False)
for ri in request_item_formset:
ri.save(commit=False)
request_item_formset.save()
return super(AdminOfferUpdateView, self).form_valid(form)
def form_invalid(self, form, request_form, request_item_formset):
return self.render_to_response(
self.get_context_data(form=form, request_form=request_form, request_item_formset=request_item_formset)
)
def get_initial(self):
self.object = self.get_object()
if self.object:
return {"request_model": self.object.request_model_name, "request_item_formset": self.object.request_model_name}
return super().initial.copy()
def get_success_url(self):
return reverse('mytarget:admin_offer_update', kwargs={'pk': self.object.id})
I solved my problem. I created a button function that creates a new model with inheritance of other model fields. In this way, there is no need to edit the form of the other model inside the form of my current model.
I have a model.form which I need to apply a queryset to filter the choices available within a select field.
class AnswerForm(ModelForm):
class Meta:
model = ProjectQuestionnaireAnswer
fields = ('answer','notes')
widgets = {
'answer': forms.Select(choices = Choice.objects.filter(question_id = 1),attrs={'class': 'form-control select2'}),
'notes': forms.Textarea(attrs={'class': 'form-control','placeholder': 'Add notes to question here'}),
}
class Choice(models.Model):
question = models.ForeignKey(ProjectQuestionnaireQuestion, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
def __str__(self):
return str(self.choice_text)
class ProjectQuestionnaireAnswer(models.Model):
YN_Choices = [
('Yes', 'Yes'),
('No', 'No'),
('Unknown', 'Unknown')
]
question = models.ForeignKey(ProjectQuestionnaireQuestion, on_delete=models.CASCADE)
answer = models.ForeignKey(Choice, on_delete=models.CASCADE,null=True)
notes = models.TextField(blank=True)
response = models.ForeignKey(ProjectQuestionnaireResponse, on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(fields=['question','response'], name='project_unique_response2'),
]
def __str__(self):
return str(self.answer)
def get_questionnaire(request, project_id, questionnaire_id):
# Get or Create the Response object for the parameters
next = request.POST.get('next', '/')
response, created = ProjectQuestionnaireResponse.objects.get_or_create(
project_name_id=project_id, questionnaire_id=questionnaire_id
)
AnswerFormSet = modelformset_factory(ProjectQuestionnaireAnswer, form=AnswerForm, fields=('answer','notes',), extra=0)
answer_queryset = ProjectQuestionnaireAnswer.objects.filter(response=response
).order_by('question__sequence'
).select_related('question')
if request.method == 'POST':
formset = AnswerFormSet(request.POST)
instances = formset.save()
return HttpResponseRedirect(next)
else:
# Get the list of questions for which no Answer exists
new_answers = ProjectQuestionnaireQuestion.objects.filter(
questionnaire__projectquestionnaireresponse=response
).exclude(
projectquestionnaireanswer__response=response
)
# This is safe to execute every time. If all answers exist, nothing happens
for new_answer in new_answers:
ProjectQuestionnaireAnswer(question=new_answer, response=response).save()
answer_formset = AnswerFormSet(queryset=answer_queryset)
return render(request, 'project_evaluation.html', {'formset': answer_formset,'project_name':response.project_name,'title':response.questionnaire.title})
I'm not sure how to write the query to only return the choices related to the question. I've tested with choices = Choice.objects.filter(question_id = 1) which does return me the choices for question 1, but need it for each question?
And then how do I present this in my template?
{{ form.answer.choices }} ??
Thanks
You need to implement it in the __init__ method.
This is my suggestion:
class AnswerForm(ModelForm):
class Meta:
model = ProjectQuestionnaireAnswer
fields = ('answer','notes')
widgets = {
'notes': forms.Textarea(attrs={'class': 'form-control','placeholder': 'Add notes to question here'}),
}
def __init__(self, *args, **kwargs):
question_id = kwargs.pop('question_id')
super().__init__(*args, **kwargs)
self.fields['answer'] = forms.ModelChoiceField(
queryset=Choice.objects.filter(question_id=question_id),
widget=forms.Select(attrs={'class': 'form-control select2'})
)
Then when initializing the form, you need to pass to it the question_id argument. For the example in the post: AnswerForm(question_id=1)
Let me know if that works.
I have a Timesheet app and I want to limit the Projects a User can allocate their time to the Projects they are working on.
MODELS My models look like this
class Project (models.Model):
name = models.CharField(
verbose_name = 'Project Title',
max_length = 80
)
code = models.CharField(
verbose_name = 'Project Code',
max_length = 15
)
supervisor = models.ForeignKey (
User,
on_delete=models.CASCADE
)
staff = models.ManyToManyField (
User,
related_name= "project_resources"
)
def __str__(self):
return u'%s' % (self.name)
class Meta:
ordering = ['name']
class Timesheet (models.Model):
user = models.ForeignKey (
User,
on_delete=models.CASCADE)
start_date = models.DateField (
verbose_name = "Start Date"
)
def __str__(self):
return u'%s | %s' % (self.user, self.start_date)
class Meta:
ordering = ['user','start_date']
class TimesheetRow (models.Model):
''' specifies a timesheet row which is unique based on Timesheet, Project and Labour Category
'''
timesheet = models.ForeignKey(
Timesheet,
on_delete=models.CASCADE
)
project = models.ForeignKey(
Project,
on_delete=models.CASCADE
)
labor = models.ForeignKey(
LaborCategory,
on_delete=models.CASCADE
)
sunday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
monday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
tuesday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
wednesday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
thursday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
friday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
saturday = models.DecimalField (default = 0, max_digits=4, decimal_places=2)
def __str__(self):
return u'%s | %s' % (self.timesheet.user, self.timesheet.start_date)
class Meta:
unique_together = ('timesheet', 'project', 'labor',)
ordering = ['timesheet', 'project','labor']
And my FORMS look like this.
class TimesheetForm(forms.ModelForm):
class Meta:
model = Timesheet
fields = ['id', 'user', 'start_date']
widgets = {
'user' : forms.HiddenInput(),
'id' : forms.HiddenInput(),
'start_date' : forms.HiddenInput(),
}
class TimesheetRowInlineForm(forms.ModelForm):
class Meta:
model = TimesheetRow
exclude =['timesheet']
widgets = {
'id' : forms.HiddenInput(),
'project' : forms.Select(attrs={'class' : 'form-control'}),
'labor' : forms.Select(attrs={'class' : 'form-control'}),
'sunday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'monday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'tuesday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'wednesday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'thursday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'friday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'saturday' : forms.NumberInput(attrs={'class' : 'form-control'}),
}
TimesheetRowInlineFormSet = forms.inlineformset_factory(
Timesheet,
TimesheetRow,
form=TimesheetRowInlineForm,
extra=1,
exclude = ['id'],
can_delete=True,
can_order=False)
This gives me a fine form and everything works fine through the views but I cannot work out how to limit the Projects dropdown on the TimesheetRowInlineForm to those users in staff.
For completeness, this is the VIEW
class TimesheetView (LoginRequiredMixin, UpdateView):
model = Timesheet
form_class = TimesheetForm
success_url = '/'
def get_start_date(self, *args, **kwargs):
try:
start_date = self.kwargs['start_date']
except:
today = datetime.date.today()
start_date = today - datetime.timedelta(7+ ((today.weekday()+1)%7) )
return start_date
def get_object(self, *args, **kwargs):
obj, created = Timesheet.objects.get_or_create(user=self.request.user, start_date=self.get_start_date())
return obj
def get_context_data(self, **kwargs):
data = super(TimesheetView, self).get_context_data(**kwargs)
if self.request.POST:
data['timesheetrows'] = TimesheetRowInlineFormSet(self.request.POST, instance=self.get_object())
else:
data['timesheetrows'] = TimesheetRowInlineFormSet(instance=self.get_object())
return data
def get_initial(self):
return { 'user': self.request.user,
'start_date' : self.get_start_date() }
def form_valid(self, form):
context = self.get_context_data()
timesheetrows = context['timesheetrows']
with transaction.atomic():
self.object = form.save()
if timesheetrows.is_valid():
timesheetrows.instance = self.object
timesheetrows.save()
return super(TimesheetView, self).form_valid(form)
EDIT
I've worked out how to do this within admin, namely:
class TimesheetRowAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
admin.site.register(TimesheetRow, TimesheetRowAdmin)
class TimesheetRowInline(admin.TabularInline):
model = TimesheetRow
can_delete = True
extra = 1
def formfield_for_foreignkey(self, db_field, request=None,**kwargs):
field = super(TimesheetRowInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'project':
if request.user is not None:
field.queryset = field.queryset.filter(staff=request._obj_.user)
if not field.queryset:
field.queryset = field.queryset.all()
else:
field.queryset = field.queryset.none()
return field
class TimesheetAdmin(admin.ModelAdmin):
list_display = ['user', 'start_date']
ordering = ['user','start_date']
inlines = [TimesheetRowInline]
def get_form(self, request, obj=None, **kwargs):
request._obj_ = obj
return super().get_form(request, obj, **kwargs)
admin.site.register(Timesheet, TimesheetAdmin)
I still need to reflect that for a non-staff user.
Having solved it in Admin above. This is how I solved it in my view. I effectively dynamically create the form within my view.
class TimesheetView (LoginRequiredMixin, UpdateView):
model = Timesheet
form_class = TimesheetForm
success_url = '/'
def create_inline_form(self):
class DynamicTimesheetRowInlineForm (forms.ModelForm):
project = forms.ModelChoiceField(queryset=Project.objects.filter(staff=self.request.user),
widget=forms.Select(attrs={'class' : 'form-control'}))
class Meta:
model = TimesheetRow
exclude =['timesheet']
widgets = {
'id' : forms.HiddenInput(),
#'project' : forms.Select(attrs={'class' : 'form-control'}),
'labor' : forms.Select(attrs={'class' : 'form-control'}),
'sunday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'monday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'tuesday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'wednesday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'thursday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'friday' : forms.NumberInput(attrs={'class' : 'form-control'}),
'saturday' : forms.NumberInput(attrs={'class' : 'form-control'}),
}
return DynamicTimesheetRowInlineForm
def get_start_date(self, *args, **kwargs):
try:
start_date = self.kwargs['start_date']
except:
today = datetime.date.today()
start_date = today - datetime.timedelta( ((today.weekday()+1)%7) )
return start_date
def get_object(self, *args, **kwargs):
obj, created = Timesheet.objects.get_or_create(user=self.request.user, start_date=self.get_start_date())
return obj
def get_context_data(self, **kwargs):
data = super(TimesheetView, self).get_context_data(**kwargs)
DynamicTimesheetRowInlineFormSet = forms.inlineformset_factory(
Timesheet,
TimesheetRow,
form=self.create_inline_form(),
extra=1,
exclude = ['id'],
can_delete=True,
can_order=False)
data['timesheetrows'] = DynamicTimesheetRowInlineFormSet(self.request.POST or None,
instance=self.get_object())
return data
def get_initial(self):
return {'user': self.request.user,
'start_date' : self.get_start_date() }
def form_valid(self, form):
context = self.get_context_data()
timesheetrows = context['timesheetrows']
print (timesheetrows.errors)
with transaction.atomic():
self.object = form.save()
if timesheetrows.is_valid():
timesheetrows.instance = self.object
timesheetrows.save()
return super(TimesheetView, self).form_valid(form)
I am creating a Health App that will take the Identity, Symptom, Disease and Treatment of the patient.
I have created models: Identity, Symptom, Disease, Treatment.
I am using form.ModelForm so that I can save the data to the db i.e. sqlite3.
I have created class based views that will handle forms, take field values, sanitize the data, and render the required form and values.
Problem: Each time I attempt to save values for the Symptom form it
seems to save it, and redirect to a new form but I am not seeing it in
the Admin Backend.
Code:
Model document
from django.db import models
from django.utils import timezone
import datetime
class Identity(models.Model):
NIS =models.CharField(max_length = 200, primary_key = True)
timestamp = models.DateTimeField(auto_now = True)
first_name = models.CharField(max_length = 80, null = True)
last_name = models.CharField(max_length = 80, null = True )
contact = models.CharField(max_length = 15, null = True)
location = models.CharField(max_length = 100, blank = True)
birthday= models.DateField(auto_now = False, auto_now_add = False, blank = True, null = True)
def __str__(self):
return '%s, %s' % (self.first_name ,self.last_name)
class Symptom(models.Model):
condition_name = models.CharField(max_length = 80, default = '')
description = models.TextField(max_length = 1000, default = '')
def __str__(self):
return self.condition_name
class Disease(models.Model):
disease_name = models.CharField(max_length = 80, default = '')
description = models.TextField(max_length = 1000, default = '')
def __str__(self):
return self.disease_name
class Treatment(models.Model):
term = models.CharField(max_length = 80, default = '')
treatment = models.TextField()
patient = models.ManyToManyField(Identity, through = 'Consultation')
date_done = models.DateField(auto_now = False, auto_now_add = False, blank = True, null = True)
def __str__(self):
return self.Term
class Consultation(models.Model):
patient_identity = models.ForeignKey(Identity)
patient_condition = models.ForeignKey(Symptom)
patient_disease = models.ForeignKey(Disease)
patient_treatment = models.ForeignKey(Treatment)
date_seen = models.DateField(auto_now = False, auto_now_add = False, blank = True, null = True)
def __str__(self):
return '%s' %(self.patient_identity)
Views document
from django.shortcuts import render, redirect
from django.views.generic import CreateView, ListView, DetailView, FormView, TemplateView
from patient.models import Identity, Symptom, Treatment, Disease, Consultation
from patient.forms import IdentityScript, SymptomScript
class Identity_view(CreateView):
model = Identity
template_name = 'patient/script.html'
def get(self, request):
form = IdentityScript()
script = Identity.objects.all()
var = {'form':form, 'script':script}
return render(request, self.template_name, var)
def post(self, request):
form = IdentityScript(request.POST)
being = None
if form.is_valid():
NIS = form.save(commit = False)
NIS.user = request.user
NIS.save()
being = form.cleaned_data['first_name']
form = IdentityScript()
return redirect('script:script')
var = {'form':form, 'being':being}
return render(request, self.template_name, var)
class Identity_list_view(ListView):
model = Identity
template_name = 'patient/Identity_list.html'
def get(self, request):
form = IdentityScript()
script = Identity.objects.all().order_by('-Timestamp')
var = {'form':form, 'script':script}
return render(request, self.template_name, var)
class Medical_document(CreateView):
model = Symptom
template_name = 'patient/medical_document.html'
def get(self, request, pk):
form = SymptomScript()
expression = Symptom.objects.all()
var = {'form':form, 'expression':expression, 'pk':pk}
return render(request, self.template_name, var)
def post(self, request, pk):
form = SymptomScript()
state = None
if form.is_valid():
manuscript = form.save(commit = False)
manuscript.user = request.user
state = form.cleaned_data['description']
manuscript.save()
patient = Identity.objects.get(pk=pk)
form = SymptomScript()
redirect('script:script')
else:
print(form)
var = {'form': form, 'state':state, 'pk':pk}
return render(request, self.template_name, var)
Forms document
from django import forms
from patient.models import Identity, Symptom, Disease
class IdentityScript(forms.ModelForm):
NIS = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder': 'Enter NIS',
'class' : 'form-control'
}
)
)
first_name = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder': 'Enter First Name',
'class' : 'form-control'
}
)
)
last_name = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder': 'Enter Last Name',
'class' : 'form-control'
}
)
)
contact = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder':'Enter Contact',
'class':'form-control'
}
)
)
born = forms.DateField(
widget = forms.TextInput(
attrs = {
'placeholder' : 'Enter Birth',
'class':'form-control'
}
)
)
location = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder':'Enter location',
'class':'form-control'
}
)
)
class Meta:
model = Identity
fields = ('NIS', 'first_name', 'last_name', 'birthday', 'location', 'contact', )
class DiseaseScript(forms.ModelForm):
disease_name = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder': 'Enter Disease Name',
'class' : 'form-control'
}
)
)
description = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder': 'Enter description',
'class' : 'form-control'
}
)
)
class Meta:
model = Disease
fields = ('disease_name', 'description')
# Create SymptomScript form
class SymptomScript(forms.ModelForm):
condition_name = forms.CharField(
widget = forms.TextInput(
attrs = {
'placeholder': 'Enter Condition Name',
'class' : 'form-control'
}
)
)
description = forms.CharField(
widget = forms.Textarea(
attrs = {
'placeholder': 'Enter Description',
'class' : 'form-control'
}
)
)
class Meta:
model = Symptom
fields = ('condition_name', 'description')
I have an application which has a form in which you can specify users by name or by formset where you select groups of users or both.
I need to add some sort of validation where the form won't proceed when sum of users selected manually and/or from groups will equal 0.
How do I make a communication between form and formset to raise validation error?
Is there another way of raising an error like in typical form and formset?
def form_valid(self, form):
context = self.get_context_data()
formset = context.get('formset')
is_valid = form.is_valid()
if formset:
is_valid &= formset.is_valid()
if not is_valid:
context['form'] = form
return self.render_to_response(context)
task = form.save()
if self.has_formset():
added_groups_list = []
for formset_form in formset:
...do something...
class TaskForm(forms.ModelForm):
sms_preview = forms.CharField(
label=u"Treść wiadomości SMS", required=False, widget=forms.Textarea(attrs={
'cols': 2,
'rows': 2,
'readonly': 'readonly',
})
)
users = forms.ModelMultipleChoiceField(User.objects.none(), label=u'Użytkownicy', required=False)
class Meta:
model = Task
fields = ('procedure', 'priority', 'location', 'message', 'date_from', 'date_to',
'users')
widgets = {
'date_from': DateTimePickerInput,
'date_to': DateTimePickerInput,
'procedure': forms.Select(attrs={'class': 'chosen',
"data-placeholder": u"Wybierz procedurę",
}),
'message': forms.Textarea(attrs={'cols': 2, 'rows': 2,
'placeholder': u"Własna treść wiadomości (opcjonalnie)"
}),
'hours': forms.TextInput(attrs={'placeholder': u'Godziny'}),
'minutes': forms.TextInput(attrs={'placeholder': u'Minuty'}),
}
def __init__(self, *args, **kwargs):
self.site = kwargs.pop('site')
self.procedure = kwargs.pop('procedure', None)
self.user = kwargs.pop('user', None)
super(TaskForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
layout = Layout('procedure')
date_from = timezone.now() + timezone.timedelta(hours=1)
self.fields['date_from'].initial = date_from.strftime("%d.%m.%Y %H:%M")
date_to = date_from + timezone.timedelta(hours=1)
self.fields['date_to'].initial = date_to.strftime("%d.%m.%Y %H:%M")
self.fields['date_from'].required = True
self.fields['date_to'].required = True
self.fields['message'].label = ""
self.fields['users'].widget.attrs = {
'class': 'chosen',
'data-placeholder': u'Nie wybrano użytkowników.',
'readonly': 'readonly',
'disabled': 'disabled',
}
class TaskActionGroupFormset(forms.formsets.BaseFormSet):
def __init__(self, *args, **kwargs):
self.site = kwargs.pop('site')
self.procedure = kwargs.pop('procedure', None)
super(TaskActionGroupFormset, self).__init__(*args, **kwargs)
#cached_property
def forms(self):
return [self._construct_form(i, site=self.site, procedure=self.procedure)
for i in xrange(self.total_form_count())]
#property
def empty_form(self):
form = self.form(
auto_id=self.auto_id,
prefix=self.add_prefix('__prefix__'),
empty_permitted=True,
site=self.site,
)
self.add_fields(form, None)
return form
Since you are using Django forms, you'll want to use the clean() method and override it to run your validation.