Additional help text to form in Django - python

When I create or edit model CV, I need to input some data in birth_date field. It's working, but I want to add some additional text to define some date format like (yyyy-mm-dd). I'm using cripsy forms for better look of forms. How can I add this help text ?
my code:
template.html
{% block profile %}
<div class="jumbotron">
<h2>Edit your basic informations</h2>
<hr>
<form method="POST" class="post-form" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
</div>
{% endblock %}
models.py
class Cv(models.Model):
author = models.ForeignKey('auth.User')
name = models.CharField(max_length=25, null = True)
surname = models.CharField(max_length=25, null = True)
city = models.CharField(max_length=100, blank=True)
birth_date = models.DateField(blank=True, null=True)
email = models.EmailField(max_length=50, null=True)
main_programming_language = models.CharField(max_length=15, null = True)
specialization = models.CharField(max_length=30, blank=True, null=True)
interests = models.TextField(blank=True, null=True)
summary = models.TextField(blank=True, null=True)
#thumbnail = models.FileField(upload_to=get_upload_file_name, blank=True)
#property
def age(self):
return int((datetime.datetime.now().date() - self.birth_date).days / 365.25 )
def zapisz(self):
self.save()
def __str__(self):
return self.surname.encode('utf-8')
forms.py
class CvForm(forms.ModelForm):
class Meta:
model = Cv
fields = ('name', 'surname', 'city', 'birth_date', 'email', 'main_programming_language', 'specialization', 'interests', 'summary',)
views.py
#login_required
def new_cv(request):
if request.method == "POST":
form = CvForm(request.POST, request.FILES)
if form.is_valid():
cv = form.save(commit=False)
cv.author = request.user
cv.save()
return redirect('proj.views.cv_detail', pk=cv.pk)
else:
form = CvForm()
return render(request, 'new_cv.html', {'form': form})

Can add help_text to your model fields:
birth_date = models.DateField(blank=True, null=True, help_text="format (yyyy-mm-dd)")
see more Django Model and Form docs.
You can also use external library JQuery Tooltip too.

Related

How to save foreign key data using forms.py?

urls.py
...
path('restaurant/menu/', r_view.Menu, name='menu'),
...
menu.html
<form method="POST" id="menuForm" autocomplete="off" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-inline">
<div class="form-group mb-4">
{{ form.item|as_crispy_field }}
</div>
<div class="form-group mb-4">
{{ form.itemImage|as_crispy_field }}
</div>
<div class="form-group mb-4">
{{ form.price|as_crispy_field }}
</div>
<div class="form-group mb-4">
{{ form.category|as_crispy_field }}
</div>
</div>
<button type="submit" class="col-md-12 myBtn">Submit</button>
</form>
views.py
def Menu(request, restaurantID):
restaurant = get_object_or_404(Restaurant_Account, restaurantID=restaurantID)
form = MenuForm()
if request.method == 'POST':
form = MenuForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.restaurant = restaurant
instance.save()
messages.success(request, "Saved successfully!")
return redirect('r_index')
context = {'form':form}
return render(request, 'restaurant/menu.html', context)
forms.py
class MenuForm(forms.ModelForm):
restaurantID = Restaurant_Account.objects.filter(restaurantID='restaurantID')
item = forms.CharField(required=True)
itemImage = forms.ImageField(required=False, label='Item image')
price = forms.DecimalField(required=True)
category = forms.ChoiceField(choices=CATEGORY)
class Meta:
model = Menu
fields = ('item', 'itemImage', 'price', 'category')
models.py
class Restaurant(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
is_restaurant = models.BooleanField(default=True)
restaurantID = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
isActive = models.BooleanField(default=True)
image = models.ImageField(upload_to='images/', blank=True)
website = models.URLField(blank=True, unique=False)
country = models.CharField(max_length=50)
def __str__(self):
return self.user.username
class Menu(models.Model):
menuID = models.AutoField(primary_key=True)
restaurantID = models.ForeignKey(Restaurant_Account, on_delete=models.CASCADE, default=None)
item = models.CharField(max_length=100)
itemImage = models.ImageField(upload_to='images/', blank=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
category = models.CharField(
max_length=20,
choices=[('', 'Choose category'),('Appetizer', 'Appetizer'),('Entree', 'Entree'),('Drink', 'Drink'),('Dessert', 'Dessert'), ('Side', 'Side')])
def __str__(self):
return self.item
I'm new to Django.
I made a form for saving menu data. If the user fills the form and click the submit button every data should be saved in the Menu table. I have no idea how to save restaurantID, which is a foreign key that refers to the Restaurant table, automatically. (By automatically I mean without the user entering input) Can somebody help me with this?
You haven't need to do all these things, if you have made restaurantID a foreign key while defining the model that is Menu, django itself handles it.
Below code might work for you:
forms.py
class MenuForm(forms.ModelForm):
item = forms.CharField(required=True)
itemImage = forms.ImageField(required=False, label='Item image')
price = forms.DecimalField(required=True)
category = forms.ChoiceField(choices=CATEGORY)
class Meta:
model = Menu
fields = ('item', 'itemImage', 'price', 'category')
views.py
def menu(request):
if request.method == 'POST':
form = MenuForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, "Saved successfully!")
return redirect('r_index')
else:
form=MenuForm()
return render(request, 'restaurant/menu.html', {'form':form})
optional: You also don't need to write this line menuID = models.AutoField(primary_key=True) in Menu model, as django makes id column by default for AutoField.
Update:
Make your models.py in this way:
MY_CHOICES=[
('', 'Choose category'),
('Appetizer', 'Appetizer'),
('Entree', 'Entree'),
('Drink', 'Drink'),
('Dessert', 'Dessert'),
('Side', 'Side')
]
class Restaurant(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
is_restaurant = models.BooleanField(default=True)
name = models.CharField(max_length=200)
isActive = models.BooleanField(default=True)
image = models.ImageField(upload_to='images/', blank=True)
website = models.URLField(blank=True, unique=False)
country = models.CharField(max_length=50)
def __str__(self):
return self.user.username
class Menu(models.Model):
restaurant= models.ForeignKey(Restaurant, on_delete=models.CASCADE, default=None)
item = models.CharField(max_length=100)
itemImage = models.ImageField(upload_to='images/', blank=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
category = models.CharField(
max_length=20,
choices=MY_CHOICES)
def __str__(self):
return self.item
Remove your AutoField, django by default make id which is primary key.
Don't forget to run makemigrations and migrate, after doing this, if it still gives error, so comment your all models and then run.

How to compare data from two models in Modelform Django

I'm creating an ebay like auction site where users can bid on an item they like and if the bid is higher than the last bid, the bid amount displayed would update to the newest bid.
I want to run validation on the modelform to compare the first amount (that the person that created the listing) inputted with the last bid (that the new user inputted).
The problem is that they are in two different models and I'm not sure how to validate both without an error
FORMS.PY
class BidForm(forms.ModelForm):
class Meta:
model = Bids
fields = ['new_bid']
labels = {
'new_bid': ('Bid'),
}
def clean_new_bid(self):
new_bid = self.cleaned_data['new_bid']
current_bid = self.cleaned_data['current_bid']
if new_bid <= current_bid:
error = ValidationError("New bid must be greater than the previous bid")
self.add_error('new_bid', error)
return new_bid
MODELS.PY
class Auction(models.Model):
title = models.CharField(max_length=25)
description = models.TextField()
current_bid = models.IntegerField(null=False, blank=False)
image_url = models.URLField(verbose_name="URL", max_length=255, unique=True, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(Category, max_length=12, null=True, blank=True, on_delete=models.CASCADE)
is_active = models.BooleanField(default=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Meta:
ordering = ['-created_at']
class Bids(models.Model):
auction = models.ForeignKey(Auction, on_delete=models.CASCADE, related_name='bidding', null=True)
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='bidding')
new_bid = models.IntegerField()
done_at = models.DateTimeField(auto_now_add=True)
VIEWS.PY
#login_required
def make_bid(request, listing_id):
auction = Auction.objects.get(pk=listing_id)
user = request.user
if request.method == 'POST':
bid_form = BidForm(request.POST)
if bid_form.is_valid():
new_bid = request.POST['new_bid']
current_price = Bids.objects.create(
listing_id = listing_id,
user = user,
new_bid = new_bid
)
messages.success(request, 'Successfully added your bid')
return HttpResponseRedirect(reverse("listing_detail", args=(listing_id,)))
else:
bid_form = BidForm(request.POST)
return render(request, 'auctions/details.html', {"bid_form": bid_form})
return render(request, 'auctions/details.html', bid_form = BidForm())
DETAILS.HTML
<p>{{ detail.description }}</p>
<hr>
<p>Current price: ${{detail.current_price}}</p>
<form action="{% url 'make_bid' detail.id %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.errors }}
{{ bid_form }}
<input type="submit" class="btn btn-primary btn-block mt-3" value="Place bid">
</form>
I'm having this error
KeyError at /make_bid/2
'current_bid'
Request Method:
POST
Request URL:
http://127.0.0.1:8000/make_bid/2
I'm sure its because I'm trying to compare two different models, but don't know a better way to do this. Could you please direct me or is there a better way to run this bid validation process?

Django: ValidationError ['ManagementForm data is missing or has been tampered with']

Django: ValidationError ['ManagementForm data is missing or has been tampered with'] i have been getting this error when i use the forminline factory module, im sorry if my question isnt placed properly, this is my first time here.
my form template is this:
{% extends 'accounts/main-form.html'%}
{% load static %}
{% block title %}
<title>CRM | Form</title>
{% endblock %}
{% block link %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style1.css'%}">
{% endblock %}
{% block content %}
<div class="container">
<form action="" method="POST">
{{formset.management_form}}
{% for i in formset %}
{{i}}
{% endfor %}
<input type="submit" class="btn" value="submit">
</form>
</div>
{% endblock%}
this is the form code in views.py
def order_form(request, pk):
customers = Customer.objects.get(id=pk)
OrderFormSet = inlineformset_factory(Customer, Order, fields=('product', 'status',))
formset = OrderFormSet(request.POST)
if request.method == 'POST':
formset = OrderFormSet(request.POST, instance=customers)
if formset.is_valid():
formset.save()
return redirect('/')
context = {'formset': formset}
return render(request, 'accounts/order_form.html', context)
my models
from django.db import models
# Create your models here.
class Customer(models.Model):
name = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
class Product(models.Model):
CATEGORY = (
('Indoor', 'Indoor'),
('OutDoor', 'Outdoor')
)
name = models.CharField(max_length=200, null=True)
price = models.FloatField(null=True)
category = models.CharField(max_length=200, null=True, choices=CATEGORY)
description = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True)
tag = models.ManyToManyField(Tag)
def __str__(self):
return self.name
class Order(models.Model):
STATUS = (
('Pending', 'Pending'),
('Out for delivery', 'Out for delivery'),
('Delivered', 'Delivered')
)
customer = models.ForeignKey(Customer, null=True, on_delete= models.DO_NOTHING)
product = models.ForeignKey(Product, null=True, on_delete= models.DO_NOTHING)
date_created = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=200, null=True, choices=STATUS)
def __str__(self):
return self.product.name
my form.py
from django.forms import ModelForm
from .models import Order
class Order_form(ModelForm):
class Meta:
model = Order
fields = ['product', 'status']

Form is not saving in database when submitted

I am working on a project on Django, where user can input values on form and submit using POST request. When form is submitted, datas are not saved in database. How do I implement save data when form is submitted.
Models:
class DataInfo(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
beneficiary_name = models.CharField(max_length=250, blank=True)
beneficiary_bank_name = models.CharField(max_length=250, blank=True)
beneficiary_account_no = models.CharField(max_length=250, blank=True)
beneficiary_iban = models.CharField(max_length=250, blank=True)
beneficiary_routing_no = models.CharField(max_length=250, blank=True)
amount = models.IntegerField(blank=True)
date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'DataInfo'
verbose_name_plural = 'DataInfo'
ordering = ['-date']
'''Method to filter database results'''
def __str__(self):
return self.user.username
Views:
#login_required
def TransferView(request):
form = DataForm(request.POST)
if request.method == "POST":
if form.is_valid():
pp = form.save(commit=False)
pp.user = request.user
pp.save()
return redirect('site:transfer_cot')
else:
form = DataForm()
context = {
'form':form
}
return render(request, 'transfer.html', context)
Forms:
class DataForm(forms.ModelForm):
class Meta:
model = DataInfo
fields = ('beneficiary_name', 'beneficiary_bank_name', 'beneficiary_account_no', 'beneficiary_iban', 'beneficiary_routing_no', 'amount')
Template:
<form method="POST" action="{% url 'site:transfer_cot' %}">
{% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-secondary">Submit</button>
</form>

ImageField() not saving images in ModelForm - Django/Python

When I try to upload a picture from my form, everything processes, but the image is not being saved.
Does anyone know why this is happening?
Thanks ahead of time!
models.py:
class Photo(models.Model):
user = models.ForeignKey(MyUser, null=False, blank=False)
category = models.ForeignKey("Category", default=1, null=True, blank=True)
title = models.CharField(max_length=30, null=True, blank=True)
description = models.TextField(max_length=120, null=True, blank=True)
image = models.ImageField(upload_to='user/photos/', null=True, blank=True)
slug = models.SlugField(null=True, blank=True)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, null=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True, null=True)
class Meta:
unique_together = ('slug', 'category')
ordering = ['-timestamp']
def __unicode__(self):
return "%s" %(self.user)
views.py:
def photo_upload_view(request, username):
u = MyUser.objects.get(username=username)
if request.method == 'POST':
form = PhotoUploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, "Thank you! You have successfully posted your picture!")
return HttpResponseRedirect('/')
else:
form = PhotoUploadForm()
submit_btn = "Upload Post"
context = {
"form": form,
"submit_btn": submit_btn
}
return render(request, "photos/photo_upload.html", context)
forms.py:
class PhotoUploadForm(forms.ModelForm):
class Meta:
model = Photo
fields = ('user', 'category', 'title', 'description', 'image')
.html:
<form method='POST' action='{{ action_url }}'>{% csrf_token %}
{{ form|crispy }}
<input class='btn btn-default {{ submit_btn_class }}' type='submit' value='{{ submit_btn }}'/>
</form>
You should add the enctype=multipart/form-data attribute to the <form> tag:
<form method='POST' action='{{ action_url }}' enctype='multipart/form-data'>
except for adding enctype=multipart/form-data, another possible reason that your image is not saving in modelform can be adding request.FILES in your POST condition:
if request.method == 'POST':
form = forms.ProjectCreateForm(request.POST, instance=project)
should be:
if request.method == 'POST':
form = forms.ProjectCreateForm(request.POST, request.FILES, instance=project)
data.profile_pic = request.FILES['profile_pic']
use request.FILES

Categories