I am creating a ticket app in my django project. When I try to create a ticket the NOT NULL constraint failed: tickets_ticket.name error shows up. I'm not sure why the value for ticket.name field won't pass correctly. How do I proceed? any help is much appreciated.
Here's what i have so far
models.py
class Category(models.Model):
name = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
class Ticket(models.Model):
STATUS = (
(True, 'Open'),
(False, 'Closed')
)
PRIORITIES = (
('None', 'None'),
('Low', 'Low'),
('Medium', 'Medium'),
('High', 'High')
)
TYPE = (
('Misc', 'Misc'),
('Bug', 'Bug'),
('Help Needed', 'Help Needed'),
('Concern', 'Concern'),
('Question', 'Question')
)
host = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True, related_name='host')
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='category')
name = models.CharField(max_length=200, null=True)
status = models.BooleanField(choices=STATUS, default=True)
priority = models.TextField(choices=PRIORITIES, default='None', max_length=10)
type = models.TextField(choices=TYPE, default='Misc', max_length=15)
description = RichTextField(null=True, blank=True)
# description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(CustomUser, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-updated', '-created']
def __str__(self):
return self.name
views.py
view for creating a ticket
def createTicket(request):
form = TicketForm()
categories = Category.objects.all()
if request.method == 'POST':
category_name = request.POST.get('category')
category, created = Category.objects.get_or_create(name=category_name)
ticket = Ticket.objects.create(
host = request.user,
category=category,
name=request.POST.get('name'),
status=request.POST.get('status'),
priority=request.POST.get('priority'),
type=request.POST.get('type'),
description=request.POST.get('description'),
)
return redirect('ticket', pk=ticket.id)
context = {'form': form, 'categories': categories}
return render(request, 'projects/ticket_form.html', context)
view for ticket page
def ticket(request, pk):
ticket = Ticket.objects.get(id=pk)
ticket_messages = ticket.message_set.all()
participants = ticket.participants.all()
if request.method == 'POST':
message = Message.objects.create(
user=request.user,
ticket=ticket,
body=request.POST.get('body')
)
ticket.participants.add(request.user)
return redirect('ticket', pk=ticket.id)
context = {'ticket': ticket, 'ticket_messages': ticket_messages,
'participants': participants}
return render(request, 'projects/ticket.html', context)
here is part of the template for the ticket page
<div class="main-column">
<form action="" method="POST">
{% csrf_token %}
<div class="form__group">
<label for="ticket_name">Ticket Name</label>
{{form.name}}
</div>
<div class="form__group">
<label for="ticket_description">Ticket Description</label>
{{form.description}}
</div>
</form>
</div>
ticket form
class TicketForm(ModelForm):
description = forms.CharField(widget = CKEditorWidget())
class Meta:
model = Ticket
fields = '__all__'
exclude = ['host', 'participants']
Related
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.
I am trying to perform below process in my Django application:
Adding member to 'Member' table whenever a user registers.
Creating tasks to populate 'Task' table.
Allocating the 'unallocated tasks' to member and hence populating Allocation table.
I see the data submitted is passed through request.POST but my table is not updated with the same data.
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Member(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
DESIGNATION = [
('Developer', 'Developer'),
('Tester', 'Tester'),
('Support', 'Support'),
]
name = models.CharField(max_length=200, null=True)
role = models.CharField(max_length=100, null=True, choices=DESIGNATION)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.name
class Task(models.Model):
CATEGORY = [
( 'Low', 'Low'),
('Medium', 'Medium'),
('Urgent', 'Urgent'),
]
STATUS = [
('Not Started', 'Not Started'),
('In Progress', 'In Progress'),
('Completed', 'Completed'),
]
name = models.CharField(max_length=200, 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, null=True)
member = models.ForeignKey('Member', null=True, on_delete=models.SET_NULL)
task_status = models.CharField(max_length=200, null=True, choices=STATUS)
def __str__(self):
return self.name
class Allocation(models.Model):
member = models.ForeignKey('Member', null=True, on_delete=models.SET_NULL)
task = models.OneToOneField('Task', null=True, primary_key=True, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.task.name
views.py
def allocate_task(request):
try:
unallocated_tasks = Task.objects.get(member__isnull=True)
except Task.DoesNotExist:
unallocated_tasks = None
if unallocated_tasks == None:
return redirect('error')
else:
form = TaskAllocateForm(instance=unallocated_tasks)
if request.method == 'POST':
form = TaskAllocateForm(request.POST, instance=unallocated_tasks)
if form.is_valid():
form.save()
return redirect('/')
context = {
'form':form,
}
return render(request, 'ttt/allocate_task.html', context)
forms.py
class TaskAllocateForm(ModelForm):
class Meta:
model = Task
fields = '__all__'
html file
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p> Allocate tasks </p>
{{ form.as_table }}
<input type="submit" name="Submit"></input>
</form>
Does it have to do something with my model definitions of Allocation model??
Models
attendance_choices = (
('absent', 'Absent'),
('present', 'Present')
)
class Head_of_department(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.CharField(max_length=30)
def __str__(self):
return self.first_name
class Employee(models.Model):
first_name = models.CharField(max_length=200, unique=True)
last_name = models.CharField(max_length=200, unique=True)
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
email = models.EmailField(max_length=100)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Attendance(models.Model):
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
employee = models.ForeignKey('Employee', on_delete=models.CASCADE, )
attendance = models.CharField(max_length=8, choices=attendance_choices, blank=True)
Views
class Attendancecreate(CreateView):
model = Attendance
fields = ['employee']
success_url = '/dashboard/'
def get_context_data(self,** kwargs):
context = super(Attendancecreate, self).get_context_data(**kwargs)
context['formset'] = AttendanceFormset(queryset=Attendance.objects.none())
context['attendance_form'] = Attendanceform()
email = self.request.user.email
hod = Head_of_department.objects.get(email=email)
context["employees"] = Employee.objects.filter(head_of_department =hod)
return context
def get_initial(self):
email = self.request.user.email
hod = Head_of_department.objects.get(email=email)
initial = super(Attendancecreate , self).get_initial()
initial['employee'] = Employee.objects.filter(head_of_department=hod)
return initial
def post(self, request, *args, **kwargs):
formset = AttendanceFormset(request.POST)
if formset.is_valid():
return self.form_valid(formset)
def form_valid(self, formset):
instances = formset.save(commit=False)
for instance in instances:
instance.head_of_department = get_object_or_404(Head_of_department, email=self.request.user.email)
instance.save()
return HttpResponseRedirect('/dashboard/')
Forms
class Attendanceform(ModelForm):
class Meta:
model = Attendance
fields = ('employee','attendance','head_of_department')
AttendanceFormset = modelformset_factory(Attendance,fields=('attendance',))
Template
{% csrf_token %}
{{ formset.management_form }}
{% for employee in employees %}
{% for form in formset %}
{{employee.first_name}} {{ form }}
{ % endfor %}<br><br>
{% endfor %}
The webapp has a login feature. The headofdepartment can mark the attendance . List of employees are rendered in the template without any issues , I want to mark attendance to the respective employees sorted in ascending order of their first_name .
That is when marking attendance employees will be listed in template, and to the right attendance form will be displayed for all the employees . It is saving only one object and not assigning the initial value for employee
Requirement :
Following dirkgroten I was able to solve the issue, answer allow to render a list employees under the head_of_department(logged in hod) and mark respective attendance .
Models
attendance_choices = (
('absent', 'Absent'),
('present', 'Present')
)
class Head_of_department(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.CharField(max_length=30)
def __str__(self):
return self.first_name
class Employee(models.Model):
first_name = models.CharField(max_length=200, unique=True)
last_name = models.CharField(max_length=200, unique=True)
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
email = models.EmailField(max_length=100)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Attendance(models.Model):
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
employee = models.ForeignKey('Employee', on_delete=models.CASCADE, )
attendance = models.CharField(max_length=8, choices=attendance_choices, blank=True)
Views
class Attendancecreate(CreateView):
model = Attendance
form_class = Attendanceform
success_url = '/dashboard/'
def get_context_data(self,** kwargs):
context = super(Attendancecreate, self).get_context_data(**kwargs)
context['formset'] = AttendanceFormset(queryset=Attendance.objects.none(), instance=Head_of_department.objects.get(email=self.request.user.email), initial=[{'employee': employee} for employee in self.get_initial()['employee']])
return context
def get_initial(self):
email = self.request.user.email
head_of_department = Head_of_department.objects.get(email=email)
initial = super(Attendancecreate , self).get_initial()
initial['employee'] = Employee.objects.filter(head_of_department=head_of_department)
return initial
def post(self, request, *args, **kwargs,):
formset = AttendanceFormset(request.POST,queryset=Attendance.objects.none(), instance=Head_of_department.objects.get(email=self.request.user.email), initial=[{'employee': employee} for employee in self.get_initial()['employee']])
if formset.is_valid():
return self.form_valid(formset)
def form_valid(self,formset):
instances = formset.save(commit=False)
for instance in instances:
instance.head_of_department = get_object_or_404(Head_of_department, email=self.request.user.email)
instance.save()
return HttpResponseRedirect('/dashboard/')
Forms
class Attendanceform(ModelForm):
class Meta:
model = Attendance
widgets = {'employee' : HiddenInput}
fields = ('employee','attendance','hod')
AttendanceFormset = inlineformset_factory(Head_of_department,Attendance,form=Attendanceform,fields=('attendance','employee'))
Template
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.employee.initial }} {{ form.employee}} {{ form.attendance }}
<br><br>
{% endfor %}
I have a form field in Django called Label. My problem is that the field shows the Labels of all users while I only want to show self created labels.
models
class Label(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
tag = models.CharField(max_length=25)
def __str__(self):
return self.tag
class Birthday(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=25, default="")
day = models.DateField()
label = models.ForeignKey(Label, on_delete=models.SET_NULL, default=0, null=True, blank=True)
def __str__(self):
return self.name
forms
class BirthdayForm(forms.ModelForm):
class Meta:
model = Birthday
fields = ('name', 'day', 'label')
class LabelForm(forms.ModelForm):
class Meta:
model = Label
fields = ('tag',)
template
<form method="POST">{% csrf_token %}
<table border="0">
{{ form }}
</table>
<button class="submitButton" type="submit">Submit</button>
</form>
This is the view for this template
view
#login_required
def index(request):
if request.method == "POST":
form = BirthdayForm(request.POST)
if form.is_valid():
birthday = form.save(commit=False)
birthday.user = request.user
birthday.save()
return redirect('index')
else:
#default_labels("Friend", request)
#default_labels("Family", request)
form = BirthdayForm()
birthday = Birthday.objects.filter(user=request.user)
username = request.user
return render(request, 'bd_calendar/index.html', {'form': form, 'birthday': birthday, 'username': username })
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.