I'm trying to pre populate an image field in a django form, however, I can't seem to get it working. Here's what I've done:
Views.py
class EditUnpublished(TemplateView):
template_name = 'adminpage/editUnpublished.html'
def get(self, request, id):
if not is_authenticated(request.user):
return render(request, template_name_not_authenticated)
post = Unpublished.objects.get(id=id)
form = PublishForm(
{
'title': post.title,
'text': post.text,
'user': post.user,
'image': post.image.url,
'users': post.users,
'tags': post.tags,
'copyeditor': post.copyeditor,
'comments': post.comments,
}
)
if not(request.user == post.copyeditor):
form.fields['comments'].widget.attrs['readonly'] = True
context = {
'post': post,
'form': form
}
return render(request, self.template_name, context)
Forms.py
class PublishForm(forms.ModelForm):
title = forms.CharField(required=False)
text = forms.TextInput()
image = forms.ImageField(required=False)
users = forms.ModelChoiceField(queryset=User.objects.all(),
widget=forms.Select(), required=False)
tags = forms.ModelChoiceField(queryset=Tags.objects.all(),
widget=forms.Select(), required=False)
copyeditor = forms.ModelChoiceField(queryset=User.objects.filter(groups__name__in=['Editor']),
required=False, to_field_name="id")
comments = forms.CharField(widget=forms.Textarea(), required=False)
class Meta:
model = PostsTwo
fields = ('title', 'text', 'image', 'users', 'copyeditor',
'tags', 'comments')
Models.py
class Unpublished(models.Model):
title = models.CharField(max_length=500)
user = models.ForeignKey(User, related_name="owner", default=None,
on_delete=models.CASCADE, blank=True, null=True)
text = models.TextField()
image = models.FileField(upload_to='img', default='img/None/no-
img.jpg', blank=True, null=True)
created_at = models.DateTimeField(default=datetime.now, blank=True)
users = models.ForeignKey(User, related_name='contributors',
on_delete=models.CASCADE, blank=True, null=True)
tags = models.ForeignKey(Tags, on_delete=models.CASCADE,
blank=True, null=True, unique=False)
copyeditor = models.ForeignKey(User, unique=False,
limit_choices_to={'groups__name': "Editor"}, on_delete=models.CASCADE,
blank=True, null=True)
comments = models.CharField(max_length=500000, blank=True,
null=True)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "Unpublished"
What I want is that when a user clicks in to a post, a form with all existing data, that's in the database, is pre populated. Everything except the image is being pre populated. What can I do? :)
Related
I want to prefill some one to many fields and also hide these field because I want to avoid a scenario where a user can see all the records related to the fields. The problem I'm facing is when I use 'all' on the form fields I the initial data dictionary is working well, but if I try to use a list of the fields I want displayed, the initial data is not getting passed into the form.
Here is my models.py:
class Agent(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
first_name = models.CharField(max_length=15, null=True, blank=True,)
surname = models.CharField(max_length=15, null=True, blank=True,)
provcoord = models.ForeignKey(Provcoord, null=True, blank=True, on_delete=SET_NULL)
regcoord = models.ForeignKey(Regcoord, null=True, blank=False, on_delete=SET_NULL)
region = models.CharField(max_length=15, null=False, blank=True, choices=REGION)
province = models.CharField(max_length=15, null=False, blank=False, choices=PROVINCE)
id_no = id_no = models.CharField(max_length=10, null=False, blank=False, unique=True,)
agent_no = models.CharField(default="Not Assigned", max_length=20, null=False, blank=False)
address = models.TextField(null=False, blank=False)
gender = models.CharField(max_length=20, null=False, blank=False, choices=GENDER)
profile_pic = models.ImageField(upload_to="assets", default="default.png")
is_blacklisted = models.BooleanField(default=False)
reason_for_blacklist = models.TextField(max_length=500, null=True, blank=True)
registered_at = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse("agent", kwargs={'str' :str.id})
def __str__(self):
return self.user.username
class Adult(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
agent = models.ForeignKey(Agent, null=True, blank=True, on_delete=SET_NULL)
regcoord = models.ForeignKey(Regcoord, null=True, blank=True, on_delete=SET_NULL)
provcoord = models.ForeignKey(Provcoord, null=True, blank=True, on_delete=SET_NULL)
surname = models.CharField(max_length=150, null=False, blank=False)
first_name = models.CharField(max_length=150, null=False, blank=False)
other_name = models.CharField(max_length=150, null=True, blank=True)
address = models.CharField(max_length=200, null=True, blank=True)
region = models.CharField(max_length=15, null=True, blank=True,choices=PROVINCE)
dob = models.CharField(max_length=10, null=False, blank=False)
gender = models.CharField(max_length=20, null=False, blank=False, choices=GENDER)
id_no = models.CharField(max_length=12, null=False, blank=False, unique=True)
receipt_no = models.CharField(max_length=10, default="Not Receipted", null=True,
blank=True)
phone_no = models.CharField(max_length=20, null=False, blank=False,)
marital_status = models.CharField(max_length=20, null=False, blank=False, choices=MARITAL_STATUS)
views.py:
def add_parent(request,):
agent = request.user.agent
regcoord = request.user.agent.regcoord
provcoord = request.user.agent.provcoord
region = request.user.agent.region
province = request.user.agent.province
form = ParentForm(initial={
'agent' :agent,
'regcoord' :regcoord,
'provcoord' :provcoord,
'region' :region,
'province' :province
})
if request.method == 'POST':
form = ParentForm(request.POST, request.FILES,)
if form.is_valid():
form.save()
return redirect('/')
context = {'form' :form}
return render(request, 'kyc/add_adult.html', context)
forms.py:
class ParentForm(ModelForm):
class Meta:
model = Adult
fields = ['surname',
'first_name',
'other_name',
'address',
'dob',
'gender',
'id_no',
'receipt_no',
'phone_no',
'image'
]
Please Help on how I can get around this issue.
Here is an approach I suggest (not tested though):
from django import forms
class ParentForm(ModelForm):
agent = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
regcoord = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
provcoord = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
region = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
province = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(ParentForm, self).__init__(*args, **kwargs)
self.fields['agent'].initial = self.user.agent
self.fields['regcoord'].initial = self.user.regcoord
self.fields['provcoord'].initial = self.user.provcoord
self.fields['region'].initial = self.user.region
self.fields['province'].initial = self.user.province
class Meta:
model = Adult
fields = ['surname',
'first_name',
'other_name',
'address',
'dob',
'gender',
'id_no',
'receipt_no',
'phone_no',
'image'
]
Notes how I referenced the 5 fields (agent, regcoord, provcoord, region, province) as extra fields by declaring them as simple CharFields. So they are no longer rendered from the model as dropdown lists. Then in the method __init__ I define the initial values for each of the fields.
Your function add_parent should become:
def add_parent(request,):
form = ParentForm(user=request.user)
if request.method == 'POST':
form = ParentForm(request.POST, request.FILES,)
if form.is_valid():
form.save()
return redirect('/')
context = {'form' :form}
return render(request, 'kyc/add_adult.html', context)
Edit
Here is another alternative:
def add_parent(request,):
data = {'agent': request.user.agent, 'regcoord': request.user.regcoord, 'provcoord': request.user.provcoord, 'region': request.user.region, 'province': request.user.province}
form = ParentForm(initial=data)
if request.method == 'POST':
form = ParentForm(request.POST, request.FILES,)
if form.is_valid():
form.save()
return redirect('/')
context = {'form' :form}
return render(request, 'kyc/add_adult.html', context)
In the function add_parent, I pass the initial values in the form of a dictionary (data), to the variable initial.
Then you need to remove the __init__ method from your form. Django will take care of rendering the form with the initial values in the corresponding fields.
This is the model:
class Booking(models.Model):
booker = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
discount_code = models.CharField(max_length=50, null=True,
blank=True)
guest_no = models.PositiveIntegerField()
arrival_date = models.DateTimeField(auto_now=False,
auto_created=False, auto_now_add=False, null=True,blank=True)
departure_date = models.DateTimeField(null=True,blank=True)
is_active = models.BooleanField(default=False)
class Meta:
db_table = 'booking'
managed = True
verbose_name = 'Booking'
verbose_name_plural = 'Bookings'
class Tempbooking(models.Model):
booker = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
discount_code = models.CharField(max_length=50, null=True,
blank=True)
guest_no = models.PositiveIntegerField()
arrival_date = models.DateTimeField(auto_now=False,
auto_created=False, auto_now_add=False, null=True,blank=True)
departure_date = models.DateTimeField(null=True,blank=True)
is_active = models.BooleanField(default=False, null=True,
blank=True)
def __str__(self):
return self.first_name
class Meta:
db_table = ''
managed = True
verbose_name = 'Tempbooking'
verbose_name_plural = 'Tempbookings'
This is the form:
class BookingForm(forms.ModelForm):
discount_code = forms.CharField(required=False)
is_active = forms.HiddenInput()
class Meta:
model = Tempbooking
fields = '__all__'
widgets = {
'booker': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Your username'}),
'first_name': forms.TextInput(attrs={'class':'form-control', 'placeholder':'Enter Your First Name'}),
'last_name': forms.TextInput(attrs={'class':'form-control', 'placeholder':'Enter Your Last Name'}),
'email': forms.TextInput(attrs={'class':'form-control', 'placeholder':'Enter Your Email'}),
'guest_no': forms.NumberInput(attrs={'class':'form-control'}),
'arrival_date': forms.DateTimeInput(attrs={'class':'form-control','type':'date'}),
'departure_date': forms.DateTimeInput(attrs={'class':'form-control','type':'date'}),
'discount_code': forms.TextInput(attrs={'class':'form-control','placeholder':'If our discounted product'})
}
This is the view:
def booking(request):
form = BookingForm()
form2 = TempbookingForm()
if request.method=='POST':
form = BookingForm(request.POST)
if form.is_valid() or form2.is_valid:
form2 = TempbookingForm(form)
form2.save()
return redirect('booking')
context = {
'form': form,
}
return render(request, 'booking.html', context)
I'm trying to make it so that if the admin logs into the admin page and changes is_valid to 'True', all the information in the Tempbooking model would be saved into the booking model...Please how do i go about it?
I have been trying to build a search functionality in my app but i have stuck on querying for the foreign key field, as it doesn't return anything and the code shows no error. Below is my code.
forms.py
class StockSearchForm(forms.ModelForm):
class Meta:
model = Stock
fields = ['category', 'item_name']
My view where i implemented the search
views.py
def list_items(request):
header = 'List of items'
form = StockSearchForm(request.POST or None)
queryset = Stock.objects.all()
context = {
"form": form,
"header": header,
"queryset": queryset,
}
#Searching an item and category
if request.method == 'POST':
queryset = Stock.objects.filter(category__name__icontains=form['category'].value(),
item_name__icontains=form['item_name'].value()
)
context = {
"form": form,
"header": header,
"queryset": queryset,
}
return render(request, "list_items.html", context)
My models are as follows.
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
def __str__(self):
return self.name
class Stock(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
#category = models.CharField(max_length=50, blank=True, null=True)
item_name = models.CharField(max_length=50, blank=True, null=True)
quantity = models.IntegerField(default='0', blank=True, null=True)
receive_quantity = models.IntegerField(default='0', blank=True, null=True)
receive_by = models.CharField(max_length=50, blank=True, null=True)
issue_quantity = models.IntegerField(default='0', blank=True, null=True)
issue_by = models.CharField(max_length=50, blank=True, null=True)
issue_to = models.CharField(max_length=50, blank=True, null=True)
phone_number = models.CharField(max_length=50, blank=True, null=True)
created_by = models.CharField(max_length=50, blank=True, null=True)
reorder_level = models.IntegerField(default='0', blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=True)
last_updated = models.DateTimeField(auto_now_add=True, auto_now=False)
export_to_CSV = models.BooleanField(default=False)
def __str__(self):
return self.item_name + '' + str(self.quantity)
So what happens is, I can search just fine the "item_name" field and results come up as required, but when i attempt to search for category no error pops up but no results show up, i kinda feel it's due to some foreign key fields issues but i can't just figure it out, I will much appreciate some help, this thing has been a nightmare for quite a while.
Try doing the following. I assume the form is not being properly used.
if request.method == 'POST' and form.is_valid():
queryset = Stock.objects.filter(category__name__icontains=form.cleaned_data.get('category'),
item_name__icontains=form.cleaned_data.get('item_name')
)
Try this:
queryset=Stock.objects.filter(category__name__icontains=form['category'].value(),
item_name__icontains=form['item_name'].value())
I'm have been struggling on this for 2 days, really. I want to populate Timesheet form field from Employees model as a select field / dropdown list.
Here are my files and I tried so far.
MODEL.PY
class Employees(models.Model):
# MONTHLY = 'MONTHLY'
# SEMIMONTHLY = 'SEMIMONTHLY'
# BIWKEEKLY = 'BIWKEEKLY'
# WEEKLY = 'WEEKLY'
# DAILY = 'DAILY'
PAY_PERIODS = [
('Monthly', 'Monthly'),
('Bi-weekly', 'Bi-weekly'),
('Weekly', 'Weekly'),
('Daily', 'Daily'),
]
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
is_active = models.BooleanField(default=True, verbose_name='Employee is actives')
first_name = models.CharField(max_length=50, verbose_name='First Name.', null=True, blank=False)
middle_name = models.CharField(max_length=50, verbose_name='Middle Name or Initials.', null=True, blank=True)
last_name = models.CharField(max_length=50, verbose_name='Last Name.', null=True, blank=False)
full_name = models.CharField(max_length=50, null=True, blank=True)
phone = PhoneField(blank=True, null=True)
email = models.EmailField(max_length=150, blank=True, null=True)
state = USStateField(null=True, blank=True)
street_address = models.CharField(max_length=150, blank=True, null=True, verbose_name='Street Address.')
zip_code = models.CharField(max_length=50, blank=True, null=True, verbose_name='Zip Code.')
hourly_rate = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
pay_frequency = models.CharField(max_length=100, choices=PAY_PERIODS, blank=True)
hire_date = models.TimeField(auto_now_add=True)
def __str__(self):
return self.full_name
def save( self, *args, **kwargs ):
self.full_name = f'{self.first_name} {self.middle_name} {self.last_name}'
super().save( *args, **kwargs )
class Timesheet(models.Model):
"""A timesheet is used to collet the clock-ins/outs for a particular day
"""
employer = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
full_name = models.ForeignKey(Employees, on_delete=models.CASCADE, null=True, blank=False, verbose_name='Select YOUR Name')
start_date = models.DateField(auto_now_add=True, null=True)
end_date = models.DateField(null=True, blank=False)
time_worked = models.DateField(null=True, blank=False)
def __str__(self):
return self.full_name
VIEWS.PY # I tried both function and class based views
class TimesheetView(CreateView):
model = Timesheet
fields = ('full_name', )
# form_class = TimesheetFrom
# queryset = Employees.objects.filter()
# print(queryset)
template_name = 'users/timesheet.html'
success_url = reverse_lazy('timesheet')
#login_required
def timesheet_view(request):
if request.method == 'POST':
form = TimesheetFrom(request.POST)
if form.is_valid():
emp = form.save(commit=False)
emp.user_id = request.user.pk
emp.save()
return redirect('dashboard')
else:
form = TimesheetFrom()
context = {
'form': TimesheetFrom(),
}
return render(request, 'users/timesheet.html', context)
FORM.PY
class TimesheetFrom(forms.Form):
class Meta:
model = Timesheet
fields = '__all__'
exclude = ('employer', )
#This is the current state of the form but I did tried many approaches.
I did search extensively here (Stackoverflow) but no use case for me. Any help will be greatly appreciated with a cup of coffee.
I have a Django 'add business' view which adds a new business with an inline 'business_contact' form.
The form works fine, but I'm wondering how to write up the unit test - specifically, the 'postdata' to send to self.client.post(settings.BUSINESS_ADD_URL, postdata)
I've inspected the fields in my browser and tried adding post data with corresponding names, but I still get a 'ManagementForm data is missing or has been tampered with' error when run.
Anyone know of any resources for figuring out how to post inline data?
Relevant models, views & forms below if it helps. Lotsa thanks.
MODEL:
class Contact(models.Model):
""" Contact details for the representatives of each business """
first_name = models.CharField(max_length=200)
surname = models.CharField(max_length=200)
business = models.ForeignKey('Business')
slug = models.SlugField(max_length=150, unique=True, help_text=settings.SLUG_HELPER_TEXT)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
phone = models.CharField(max_length=100, null=True, blank=True)
mobile_phone = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(null=True)
deleted = models.BooleanField(default=False)
class Meta:
db_table='business_contact'
def __unicode__(self):
return '%s %s' % (self.first_name, self.surname)
#models.permalink
def get_absolute_url(self):
return('business_contact', (), {'contact_slug': self.slug })
class Business(models.Model):
""" The business clients who you are selling products/services to """
business = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=100, unique=True, help_text=settings.SLUG_HELPER_TEXT)
description = models.TextField(null=True, blank=True)
primary_contact = models.ForeignKey('Contact', null=True, blank=True, related_name='primary_contact')
business_type = models.ForeignKey('BusinessType')
deleted = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
address_1 = models.CharField(max_length=255, null=True, blank=True)
address_2 = models.CharField(max_length=255, null=True, blank=True)
suburb = models.CharField(max_length=255, null=True, blank=True)
city = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=40, null=True, blank=True)
website = models.URLField(null=True, blank=True)
class Meta:
db_table = 'business'
def __unicode__(self):
return self.business
def get_absolute_url(self):
return '%s%s/' % (settings.BUSINESS_URL, self.slug)
VIEWS:
def business_add(request):
template_name = 'business/business_add.html'
if request.method == 'POST':
form = AddBusinessForm(request.POST)
if form.is_valid():
business = form.save(commit=False)
contact_formset = AddBusinessFormSet(request.POST, instance=business)
if contact_formset.is_valid():
business.save()
contact_formset.save()
contact = Contact.objects.get(id=business.id)
business.primary_contact = contact
business.save()
#return HttpResponse(help(contact))
#business.primary = contact.id
return HttpResponseRedirect(settings.BUSINESS_URL)
else:
contact_formset = AddBusinessFormSet(request.POST)
else:
form = AddBusinessForm()
contact_formset = AddBusinessFormSet(instance=Business())
return render_to_response(
template_name,
{
'form': form,
'contact_formset': contact_formset,
},
context_instance=RequestContext(request)
)
FORMS:
class AddBusinessForm(ModelForm):
class Meta:
model = Business
exclude = ['deleted','primary_contact',]
class ContactForm(ModelForm):
class Meta:
model = Contact
exclude = ['deleted',]
AddBusinessFormSet = inlineformset_factory(Business,
Contact,
can_delete=False,
extra=1,
form=AddBusinessForm,
)
The problem is you have not included the management form in your data. You need to include form-TOTAL_FORMS (total number of forms in the formset, default is 2), form-INITIAL_FORMS (the initial number of forms in the formset, default is 0) and form-MAX_NUM_FORMS (the maximum number of forms in the formset, default is '').
See the Formset documentation for more information on the management form.