How to access child model from parent model in Python - django

I am trying to get data from child model through the parent model, I don't know if it possible or there is a way of doing it, and I want to know how to implement the formset concept in this context , I would be grateful for any solution
models.py
class Client_Data(models.Model):
RC = models.CharField(max_length=50)
Raison_social = models.CharField(max_length=254)
NIF = models.CharField(max_length=50,unique=True)
AI = models.CharField(max_length=50,unique=True)
NIS = models.CharField(max_length=50,unique=True)
Banque = models.CharField(max_length=50,unique=True)
CB = models.CharField(max_length=50)
adresse = models.CharField(max_length=50)
slug = models.SlugField(blank=True, unique=True)
active = models.BooleanField(default=True)
class Contact(models.Model):
client = models.ForeignKey(Client_Data,blank=True,on_delete=models.CASCADE)
Nom = models.CharField(max_length=50)
post = models.CharField(max_length=50)
Tel = models.CharField(max_length=50)
email = models.EmailField(max_length=255,unique=True)
contact_type = models.CharField(default='Client_contact',max_length=50)
views.py
def save_client_form(request, form,Contact_form, template_name):
data = dict()
if request.method == 'POST':
if form.is_valid() and Contact_form.is_valid():
client = form.save()
contact = Contact_form.save(commit=False)
contact.client = client
contact.save()
form.save()
Contact_form.save()
data['form_is_valid'] = True
books = Client_Data.objects.all()
data['html_book_list'] = render_to_string('Client_Section/partial_client_c.html', {
'client': books
})
else:
print(form.errors)
print(Contact_form.errors)
data['form_is_valid'] = False
context = {'form': form,'contact_form':Contact_form}
data['html_form'] = render_to_string(template_name, context, request=request)
return JsonResponse(data)
def client_update(request,slug):
book = get_object_or_404(Client_Data, slug=slug)
contact = Contact.objects.select_related().filter(client=book.id)
print(contact)
if request.method == 'POST':
form = ClientForm(request.POST, instance=book)
contact_form = Contact_Form(request.POST, instance=contact)
else:
form = ClientForm(instance=book)
contact_form = Contact_Form(instance=contact)
return save_client_form(request, form,contact_form ,'Client_Section/partial_client_update.html')

If I understand you correctly, you may simply do it this way:
contact = Contact.objects.select_related().filter(client=book.id)
addresse = contact.client.addresse

in you view.py
from django.forms import inlineformset_factory
from django.shortcuts import render, get_object_or_404
def client_update(request, slug):
context = {}
book = get_object_or_404(Client_Data, slug=slug)
formset = inlineformset_factory(Client_Data, Contact, form=Contact_Form )
if request.method == 'POST':
form = ClientForm(request.POST, instance=book)
contactforms = formset(request.POST, prefix='contactformset', instance=book)
context['form'] = form
context['contactforms'] = contactforms
if contactforms.is_valid() and form.is_valid():
form.save()
contactforms.save()
return HttpResponse("your data saved")
else:
return render(request, 'Client_Section/partial_client_update.html', context)
else:
form = ClientForm(instance=book)
contactforms = formset(prefix='contactformset', instance=book)
context['form'] = form
context['contactforms'] = contactforms
return render(request, 'Client_Section/partial_client_update.html', context)
in partial_client_update.html
<form method="POST">
{% csrf_token %}
{{form}}
<hr>
{% formset in contactforms %}
{{formset }}
<hr>
{% endfor %}
<button type="submit ">update</button>
</form>

Related

Add customer modal and edit in one view in django

I am kinda like stuck.
I have a BankAccountCreation() and the the form is called in a modal in Django template.
I am trying to get the same for be used for editing. but when I do that my edit button returns an empty form
My view is as below
def employee_info(request, id):
if not request.user.is_authenticated:
return redirect('/')
context = {}
banks = Bank.objects.all()
employee = get_object_or_404(Employee, id = id)
bank_instance = Bank.objects.filter(employee = employee).first()
context = {}
context['employee'] = employee
context['bank'] = bank_instance
context['banks'] = banks
context['title'] = 'profile - {0}'.format(employee.get_full_name)
if request.method == 'GET':
form = BankAccountCreation()
context['form'] = form
return render(request, 'employee/employee_info.html', context)
if request.method == 'POST':
form = BankAccountCreation(data = request.POST)
if form.is_valid():
instance = form.save(commit = False)
employee_id = request.POST.get('employee')
employee_object = employee
instance.employee = employee_object
instance.name = request.POST.get('name')
instance.branch = request.POST.get('branch')
instance.account = request.POST.get('account')
instance.code = request.POST.get('code')
instance.save()
messages.success(request, 'Bank Details Successfully Created for {0}'.format(employee_object.get_full_name), extra_tags = 'alert alert-success alert-dismissible show')
return redirect('employee_info', id=employee.id)
else:
context['form'] = form
messages.error(request, 'Error Updating details for {0}'.format(employee_object.get_full_name), extra_tags = 'alert alert-warning alert-dismissible show')
return redirect('employee_info', id=employee.id)
form = BankAccountCreation()
return render(request, 'employee/employee_info.html', context)
The Bank model has a foreign key to the Employee model

Django: change TextField before save

This is my model :
class Card(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
imp_id = models.TextField(null = True)
And here is my view :
def Add(request):
if request.method == 'POST':
form = Add_card(request.POST)
if form.is_valid():
save = form.save(commit = False)
save.user = request.user
save.imp_id = "asd" # I tried to change it here but I failed
save.save()
else:
form = Add_card()
cards = Card.objects.all()
return render(request, 'addcard.html', {'form': form, 'cards' : cards})
How can I change that textfield before save?
you can do it like this
def Add(request):
if request.method == 'POST':
request.POST.imp_id="asd"
form = Add_card(request.POST)
if form.is_valid():
save = form.save(commit = False)
save.user = request.user
save.save()
else:
form = Add_card()
cards = Card.objects.all()
return render(request, 'addcard.html', {'form': form, 'cards' : cards})
The problem could be solved by using default='asd'.

how to upload an image in comments?

i have a small form in my blog detail view and it has a name,last name,email and an image field. the first three work fine but when i add the imagefield in the form, the form wont save from the page but it works from admin page.
this is my views.py:
def campaign_detail_view(request, id):
template_name = 'gngo/campaign-detail.html'
campaign = get_object_or_404(Campaign, id = id)
comments = CampaignForm.objects.filter(campaign=campaign).order_by('-id')
form = FormCamp(request.POST)
if request.method == 'POST':
if form.is_valid():
name = request.POST.get('name')
last = request.POST.get('last')
email = request.POST.get('email')
comment = CampaignForm.objects.create(campaign=campaign,name=name,last=last,email=email)
comment.save()
return redirect('campaign-detail',id=id)
else:
form = FormCamp()
context = {
'campaign':campaign,
'comments':comments,
'form':form,
}
context["object"] = Campaign.objects.get(id = id)
return render(request, template_name, context)
and this is my comment model:
class CampaignForm(models.Model):
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
last = models.CharField(max_length=100)
email = models.EmailField()
image = models.ImageField(upload_to='images')
this is a non user form, so everyone can fill it. please help me understand how to add the ability to upload an image in this form
oh and this the form:
class FormCamp(forms.ModelForm):
class Meta:
model = CampaignForm
fields = ('name','last','email', 'image',)
THANKS ALOT FOR THE ANSWERS AND SUPPORTS
Instead of using the form to validate and then manually extracting the fields again, you should use the save method of your ModelForm and pass request.FILES to your form when creating it.
And as the campaign is not an editable field, it shall be added after creating the object.
def campaign_detail_view(request, id):
template_name = 'gngo/campaign-detail.html'
campaign = get_object_or_404(Campaign, id = id)
comments = CampaignForm.objects.filter(campaign=campaign).order_by('-id')
if request.method == 'POST':
form = FormCamp(request.POST, request.FILES)
if form.is_valid():
campaign_form = form.save(commit=False)
campaign_form.campaign = campaign
campaign_form.save()
return redirect('campaign-detail',id=id)
else:
form = FormCamp()
context = {
'campaign':campaign,
'comments':comments,
'form':form,
}
context["object"] = Campaign.objects.get(id = id)
return render(request, template_name, context)
https://docs.djangoproject.com/en/2.2/topics/forms/modelforms/#the-save-method
https://docs.djangoproject.com/en/2.2/topics/forms/#the-view
Try this:
def campaign_detail_view(request, id):
template_name = 'gngo/campaign-detail.html'
campaign = get_object_or_404(Campaign, id = id)
comments = CampaignForm.objects.filter(campaign=campaign).order_by('-id')
form = FormCamp(request.POST, request.FILES)
if request.method == 'POST':
if form.is_valid():
comment = form.save(commit=False)
comment = CampaignForm.objects.create(campaign=campaign,name=name,last=last,email=email)
comment = request.FILES['image']
comment.save()
return redirect('campaign-detail',id=id)
else:
form = FormCamp()
context = {
'campaign':campaign,
'comments':comments,
'form':form,
}
context["object"] = Campaign.objects.get(id = id)
return render(request, template_name, context)
class FormCamp(forms.ModelForm): to this;
class FormCamp(forms.Form):
Don't forget to add enctype=multipart/form-data in your form in template.

How to set initial value in the form

Hey guys how can i set initial value in my form field, let say the user click "BidForm" in the search form, i want the BidForm value will be the value of ProjectName in the other form...
here's my code in my search views
def search_views(request):
project_list = ProjectNameInviToBid.objects.all()
query = request.GET.get('query')
if query:
project_list = project_list.filter(ProjectName__icontains=query)
context = {
'project_list': project_list
}
return render(request, 'content/search_views.html', context)
and my other views
def project_name_details(request, sid):
majordetails = ProjectNameInviToBid.objects.get(id=sid)
if request.method == 'POST':
form = invitoBidForm(request.POST, request.FILES)
form.fields['ProjectName'].initial = majordetails
if form.is_valid():
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)
my form.py
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 my models.py
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
class InviToBid(models.Model):
today = date.today()
ProjectName = models.ForeignKey('ProjectNameInviToBid', on_delete=models.CASCADE)
NameOfFile = models.CharField(max_length=255, verbose_name='Name of File')
Contract_No = models.IntegerField(verbose_name='Contract No')
def __str__(self):
return self.NameOfFile
First, I shall praise your documentation. Most people fail to provide the important code.
You can add something like this to your code here that will do what you require.
An example from my own code
if request.method == 'GET' and request.user.is_authenticated:
study = Study.objects.get(pk=studyID)
form = ContactForm(initial={'from_email': request.user.email, 'subject': "Study: " + study.name ,'message': study_message.format(request.user.get_short_name(), request.user.get_full_name())})
How you should change your code
Change your code in your other views from this:
else:
form = invitoBidForm()
to
else:
form = invitoBidForm(initial={'ProjectName': <wherever your project name comes from>})

Use saved form instead of cleaned form django

I am not able to display the invoice number in the receipt.html.
invoice number is auto generated in models.py
models.py
from random import randint
class Buyer(models.Model):
name_of_buyer = models.CharField(max_length=200,null=True)
address_of_buyer = models.CharField(max_length=200,null=True)
interested_in = models.ForeignKey(Box,on_delete=models.CASCADE,null=True)
Pickup_dt = models.DateField(null=True)
Pickup_time = models.CharField(max_length=80,null=True)
Invoice_number = models.CharField(max_length=12,blank=True,unique=True)
def save(self, *args, **kwargs):
if self.interested_in == 'Mangos':
x=randint(99,99999)
self.Invoice_number = str('MAN') + str(x)
elif self.service == 'Banana':
x=randint(99,99999)
self.Invoice_number = str('BAN') + str(x)
elif self.service == 'Apple':
x=randint(99,99999)
self.Invoice_number = str('APP') + str(x)
super(imfc_one,self).save()
def __str__(self):
return str(self.Invoice_number)
forms.py
class Sale(forms.ModelForm):
def clean_interested_in(self):
buyer_interested_in_box = self.cleaned_data['interested_in']
if buyer_interested_in_box.mango < 10:
raise forms.ValidationError('Not enough fruits.Please select another box')
class Meta:
model = Buyer
fields = '__all__'
view.py
def ind(request):
form = Sale()
if request.method == 'POST':
form = Sale(request.POST)
if form.is_valid():
form.save(commit=True)
return render(request,'app_one/receipt.html',{'upform':form.cleaned_data})
else:
print("form is not vaalid")
return render(request,'app_one/index1.html',{'form':form})
receipt.html
receipt : {{ upform.Invoice_number }}
How can I have the invoice number in the receipt.html
Thank you.
You don't have to pass form.cleaned_data in view. Just pass your saved object
def ind(request):
form = Sale()
if request.method == 'POST':
form = Sale(request.POST)
if form.is_valid():
buyer = form.save(commit=True)
return render(request,'app_one/receipt.html',{'buyer': buyer})
else:
print("form is not vaalid")
return render(request,'app_one/index1.html',{'form':form})
In receipt.html, just call
receipt : {{ buyer.Invoice_number }}