I have the following models that I need to create a form which allows for the updating of an existing Response (generated previously with a slug and then emailed to the respondent) and the creation of a Rating for each CV in CV.objects.all(). What's the easiest way to do this in Django. Currently I have a class-based UpdateView for Response and that's it.
class Response(models.Model):
first_name = models.CharField(max_length=200, null=True, blank=True)
last_name = models.CharField(max_length=200, null=True, blank=True)
email = models.EmailField(max_length=254)
slug = models.SlugField(max_length=32)
submited = models.BooleanField(default=False)
submit_time = models.DateTimeField(null=True, blank=True)
creation_time = models.DateTimeField(auto_now_add=True)
class CV(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to=content_file_name)
class Rating(models.Model):
cid = models.ForeignKey('CV')
rid = models.ForeignKey('Response')
score = models.IntegerField()
comment = models.TextField()
I eventually worked out how to do this. My code was as follows in case anyone is interested.
def add_response(request):
CVs = CV.objects.all()
if request.method == "POST":
ResForm = ResponseForm(request.POST, instance=Response())
RatForms = [RatingForm(request.POST, prefix=str(cv.id), instance=Rating(cid=cv)) for cv in CVs]
if ResForm.is_valid() and all([rf.is_valid() for rf in RatForms]):
new_response = ResForm.save(commit=False)
new_response.submit_time = datetime.now()
new_response.submited = True
new_response.save()
for rf in RatForms:
new_rating = rf.save(commit=False)
new_rating.rid = new_response
new_rating.save()
return HttpResponseRedirect('/thanks/')
else:
for i, _ in enumerate(RatForms):
RatForms[i].cv = CV.objects.filter(id=int(RatForms[i].prefix))[0]
print RatForms[i].cv
return render(request, 'response.html', {'response_form': ResForm, 'rating_forms': RatForms})
else:
ResForm = ResponseForm(instance=Response())
RatForms = [RatingForm(prefix=str(cv.id), instance=Rating(cid=cv)) for cv in CVs]
for i, _ in enumerate(RatForms):
RatForms[i].cv = CV.objects.filter(id=int(RatForms[i].prefix))[0]
print RatForms[i].cv
return render(request, 'response.html', {'response_form': ResForm, 'rating_forms': RatForms})
Related
Model.py
class Branch(models.Model): # Branch Master
status_type = (
("a",'Active'),
("d",'Deactive'),
)
name = models.CharField(max_length=100, unique=True)
suffix = models.CharField(max_length=8, unique=True)
Remark = models.CharField(max_length=200, null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices = status_type, default = 'a')
def __str__(self):
return self.name
class Vendor(models.Model):
status_type = (
("a",'Active'),
("d",'Deactive'),
)
branch = models.ManyToManyField(Branch)
company = models.CharField(max_length=200)
name = models.CharField(max_length=200)
phone = models.CharField(max_length=11, unique = True)
email = models.EmailField(max_length=254, unique = True)
gst = models.CharField(max_length=15, unique = True)
pan_no = models.CharField(max_length=10, unique = True)
add_1 = models.CharField(max_length=50, null=True, blank = True)
add_2 = models.CharField(max_length=50, null=True, blank = True)
add_3 = models.CharField(max_length=50, null=True, blank = True)
Remark = models.CharField(max_length=200, null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices = status_type, default = 'a')
def __str__(self):
return self.company
form.py
i want save like created_by field
class VendorForm(ModelForm):
class Meta:
model = Vendor
fields = 'all'
exclude = ['created_by', 'branch']
widgets = {
'company':forms.TextInput(attrs={'class':'form-control'}),
'name':forms.TextInput(attrs={'class':'form-control'}),
'phone':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'}),
'gst':forms.TextInput(attrs={'class':'form-control'}),
'pan_no':forms.TextInput(attrs={'class':'form-control'}),
'add_1':forms.TextInput(attrs={'class':'form-control'}),
'add_2':forms.TextInput(attrs={'class':'form-control'}),
'add_3':forms.TextInput(attrs={'class':'form-control'}),
'Remark':forms.Textarea(attrs={'class':'form-control','rows':'2'}),
'status':forms.Select(attrs={'class':'form-control'}),
}
Views.py
I have pass branch in session.
I want to save with branch which is many to many field
def Add_Vendor(request): # for vendor add
msg = ""
msg_type = ""
branch_id = request.session['branch_id']
branch_data = Branch.objects.get(id = branch_id)
form = ""
if request.method == "POST":
try:
form = VendorForm(request.POST)
if form.is_valid:
vendor_add = form.save(commit=False)
vendor_add.created_by = request.user
vendor_add.instance.branch = branch_data.id
vendor_add.save()
form.save_m2m() # for m to m field save
msg_type = "success"
msg = "Vendor Added."
form = VendorForm(initial={'branch':branch_id})
except:
msg_type = "error"
msg = str(form.errors)
print(msg)
else:
form = VendorForm(initial={'branch':branch_id})
context = {
'form':form,
'branch_data':branch_data,
'msg_type':msg_type,
'msg':msg,
'btn_type':'fa fa-regular fa-plus',
'form_title':'Vendor Form',
'tree_main_title':'Vendor',
'v_url':'vendor_page',
'tree_title':'Add Form',
}
return render(request, 'base/vendor_master/form_vendor.html',context)
I would advise not to work with commit=False in the first place:
def Add_Vendor(request): # for vendor add
branch_id = request.session['branch_id']
branch_data = get_object_or_404(Branch, pk=branch_id)
if request.method == 'POST':
form = VendorForm(request.POST, request.FILES)
if form.is_valid():
form.instance.created_by = request.user
form.instance.branch = branch_data.id
vendor_add = form.save()
vendor_add.branch.add(branch_data)
return redirect('name-of-some-view')
else:
form = VendorForm()
context = {
'form': form,
'branch_data': branch_data,
'btn_type': 'fa fa-regular fa-plus',
'form_title': 'Vendor Form',
'tree_main_title': 'Vendor',
'v_url': 'vendor_page',
'tree_title': 'Add Form',
}
return render(request, 'base/vendor_master/form_vendor.html', context)
You can simplify your form by automatically adding form-control to each widget:
class VendorForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
attrs = field.widget.attrs
attrs['class'] = attrs.get('class', '') + ' form-control'
class Meta:
model = Vendor
exclude = ['created_by', 'branch']
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: You can set a field editable=False [Django-doc]. Then the field does not show up in the ModelForms and ModelAdmins by default. In this case for example with created_by.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: Please do not pass messages manually to the template. Django has the messages framework [Django-doc], which allows to add messages to the request, which will then be delivered the next time a template renders these messages. This makes delivering multiple messages convenient, as well as setting different log levels to the messages.
Im having trouble on uploading multiple files. The uploaded files are pdf and only one is saved.
views.py
def attachments(request):
to = TravelOrder.objects.order_by('-date_filling').last()
if request.method == 'POST':
form = AttachmentsForm(request.POST, request.FILES)
if form.is_valid():
for f in request.FILES.getlist('attachment'):
file_instance = Attachements(travel_order=to, attachment=f)
file_instance.save()
print('YEY')
return redirect('attach')
else:
form = AttachmentsForm()
context = {
'form': form
}
return render(request, 'employee/attachments.html', context)
models.py
class TravelOrder(models.Model):
created_by = models.CharField(max_length=255)
start_date = models.DateField(auto_now=False)
end_date = models.DateField(auto_now=False)
wfp = models.CharField(max_length=255, verbose_name='Wfp Where to be charged')
purpose_of_travel = models.CharField(max_length=255)
region = models.ForeignKey(Region, on_delete=models.CASCADE)
venue = models.CharField(max_length=255)
date_filling = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=15)
def __str__(self):
return self.purpose_of_travel
class Attachements(models.Model):
at_id = models.AutoField(primary_key=True)
travel_order = models.ForeignKey(TravelOrder, on_delete=models.CASCADE)
attachment = models.FileField(upload_to='attachment/')
I think you are returing before the loop finishes.
for f in request.FILES.getlist('attachment'):
file_instance = Attachements(travel_order=to, attachment=f)
file_instance.save()
print('YEY')
return redirect('attach')
Take the return outside loop, so that the redirect happens only after saving all files. That means
for f in request.FILES.getlist('attachment'):
file_instance = Attachements(travel_order=to, attachment=f)
file_instance.save()
print('YEY')
return redirect('attach')
Good days guys need help for my ForeignKey Relationship in my models,
i want my foreignkey values is equal to the user choose
Here's my model view
class ProjectNameInviToBid(models.Model):
ProjectName = models.CharField(max_length=255, verbose_name='Project Name', null=True)
DateCreated = models.DateField(auto_now=True)
def __str__(self):
return self.ProjectName
have relations to ProjectNameInviToBid
class InviToBid(models.Model):
today = date.today()
ProjectName = models.ForeignKey('ProjectNameInviToBid', on_delete=models.CASCADE, null=True)
NameOfFile = models.CharField(max_length=255, verbose_name='Name of File')
Contract_No = models.IntegerField(verbose_name='Contract No')
Bid_Opening = models.CharField(max_length=255, verbose_name='Bid Opening')
Pre_Bid_Conference = models.CharField(max_length=255, verbose_name='Pre Bid Conference')
Non_Refundable_Bidder_Fee = models.CharField(max_length=255, verbose_name='Non Refundable Fee')
Delivery_Period = models.CharField(max_length=255, verbose_name='Delivery Period')
Pdf_fileinvi = models.FileField(max_length=255, upload_to='upload/invitoBid', verbose_name='Upload Pdf File Here')
Date_Upload = models.DateField(auto_now=True)
This is my form view
class invitoBidForm(ModelForm):
class Meta:
model = InviToBid
fields = ('ProjectName','NameOfFile', 'Contract_No', 'Bid_Opening',
'Pre_Bid_Conference', 'Non_Refundable_Bidder_Fee',
'Delivery_Period',
'Pdf_fileinvi')
and Lastly this my view Forms
def project_name_details(request, sid):
majordetails = ProjectNameInviToBid.objects.get(id=sid)
if request.method == 'POST':
form = invitoBidForm(request.POST, request.FILES)
if form.is_valid():
majordetails = form.ProjectName
form.save()
messages.success(request, 'File has been Uploaded')
else:
form = invitoBidForm()
args = {
'majordetails': majordetails,
'form': form
}
return render(request,'content/invitoBid/bacadmininvitoBid.html', args)
but im have a error,, hope you can help me. thank you in advance
this is my code
views.py
def guardar(request):
if request.method == "POST":
idpersona = int(request.POST.get('id'))
persona = personal.objects.get(id=idpersona)
idep = int(request.POST.get('dependencia'))
dep = dependencia.objects.get(id=idep)
idcon = int(request.POST.get('concepto'))
con = concepto.objects.get(id=idcon)
fecha = request.POST.get('fecha')
print(fecha)
db_registro = lista_registro(
personal_id=persona,
fecha_registro=fecha,
dependencia_id=dep,
concepto_id=con,
descripcion=request.POST.get('descripcion'),
monto=request.POST.get('monto'),
)
db_registro.save()
return render(request, 'registro/exito.html')
Models.py
class lista_registro(models.Model):
personal_id = models.ForeignKey(personal, on_delete=models.CASCADE)
dependencia_id = models.ForeignKey(dependencia, on_delete=models.CASCADE)
concepto_id = models.ForeignKey(concepto, on_delete=models.CASCADE)
fecha_realizado = models.DateField()
fecha_registro = models.DateField(auto_now_add=True)
descripcion = models.CharField(max_length=1000)
pago_id = models.ForeignKey(pago, on_delete=models.CASCADE, default=2)
monto = models.CharField(max_length=100)
def __str__(self):
return "===> " + self.descripcion + " <==="
well my problem is that I get a NOT NULL constraint error. I get that this is a date error but I don't know how to solve this
when you define a field that will not be required just set null=True, blank=True on your models file
fecha_realizado = models.DateField(null=True, blank=True)
In models.py:
class Client(AbstractBaseUser):
username = models.CharField(max_length=32, unique=True)
email = models.EmailField('email address', unique=True, db_index=True)
avatar = models.ImageField('avatar', upload_to='avatars')
id = id(object)
class Order(models.Model):
class Meta():
db_table = 'order'
short_desc = models.CharField(max_length=30)
subject = models.ForeignKey(Subject, blank=True)
user_id = models.ForeignKey('Client', to_field='id', related_name='client_id', default='0', blank=True)
performer_id = models.ForeignKey('Client', to_field='id', related_name='performer_id', default='0', blank=True)
worktype = models.ForeignKey(Type, blank=True)
level = models.IntegerField(default=0, blank=True)
readiness = models.BooleanField(default=False, blank=True)
description = models.TextField(max_length=2000, blank=True)
file = models.FileField(upload_to='orderfiles', blank=True)
#maxdate = models.DateField(blank=True)
addate = models.DateField(auto_now=True, blank=True)
price = models.IntegerField(max_length=10, blank=True)
responses = models.IntegerField(blank=True)
In forms.py:
class AddOrderForm(forms.ModelForm):
short_desc = forms.CharField(widget=forms.TextInput,label="Краткое описание(послужит именем)")
subject = forms.ModelChoiceField(queryset=Subject.objects.all(), label="Предмет")
worktype = forms.ModelChoiceField(queryset=Type.objects.all(), label="Тип")
level = forms.IntegerField(widget=forms.TextInput,label="Уровень сложности (от 1 до 5)")
description = forms.CharField(widget=forms.TextInput,label="Полное описание")
#maxdate = forms.DateField(widget=forms.TextInput,label="maxdate")
price = forms.IntegerField(widget=forms.TextInput,label="Ваша цена")
responses = forms.IntegerField(widget=forms.TextInput,label="Кол-во ответов на заказ")
class Meta:
model = Order
fields = ['short_desc', 'level', 'description', 'price', 'responses', 'subject', 'worktype']
In views.py:
def addorder(request, user_id):
"""
Adding Order view
"""
if request.POST:
form = AddOrderForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
return redirect('/')
auth1 = auth.get_user(request).username
return render_to_response('customer.html', { 'form': form,'username' : auth1}, context_instance=RequestContext(request))
I need the field user_id in class Order to be initialized immediately after adding order(). Where should I do it and in which way? I need something like this logic: Client adds an Order through AddOrderForm and then user_id field of just added object of class Order has to be initialized with an object of class Client, whose id equals user_id in parameters of addorder() function.
You can do that using commit=False while saving the form. This is typical way of saving the object using model form which has fewer fields.
def addorder(request, user_id):
"""
Adding Order view
"""
if request.POST:
form = AddOrderForm(request.POST)
if form.is_valid():
order = form.save(commit=false)
order.client_id = Client.objects.get(id=user_id)
order.save()
return redirect('/')
else:
return redirect('/')
auth1 = auth.get_user(request).username
return render_to_response('customer.html',
{ 'form': form,'username' : auth1},
context_instance=RequestContext(request))
Disclaimer: Handle errors e.g. Client.objects.get() may fail. Use appropriate fields to search.