I am a beginner in django and trying to create a web application for my task.
I am trying to assign a user to every to employee.
The idea is that user(in my class Employee) brings a list of user options that have not yet been assigned to the new employee to be registered.
My model:
class Employee():
name = models.CharField(max_length=100)
job = models.CharField(max_length=30)
user = models.OneToOneField(User,on_delete=models.CASCADE)
def __str__(self):
return'{}'.format(self.name,self.job,self.user)
My form:
class EmployeeForm(forms.ModelForm):
user= forms.ModelChoiceField(queryset=User.objects.filter(id=Employee.user))
class Meta:
model = Employee
fields = [
'name',
'job',
'user'
]
My view:
def register_employee(request):
if request.method == 'POST':
form = EmployeeForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
return redirect('list_employee')
else:
form = EmployeeForm()
return render(request, 'employee/employee_form.html',{'form': form})
I guess your code to be modified as,
class EmployeeForm(forms.ModelForm):
user= forms.ModelChoiceField(queryset=User.objects.filter(employee=None))
Please try the above.
Related
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Customer(models.Model):
user = models.OneToOneField(User,null=True,blank=True,on_delete=models.CASCADE)
name = models.CharField(max_length=200,null=True)
## phone = models.IntegerField(null=True)
email = models.EmailField(max_length=250)
profile_pic = models.ImageField(default='default_pic.png',null=True,blank=True)
date_created = models.DateTimeField(auto_now_add=True,null=True)
def __str__(self):
return self.name
class Task(models.Model):
customer = models.ForeignKey(Customer,on_delete=models.CASCADE,null=True)
title = models.CharField(max_length=200)
description = models.TextField(null=True,blank=True)
complete = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
ordering = ['complete']
views.py
#login_required(login_url='login')
def taskCreate(request):
if request.method == 'POST':
form = TaskForm(request.POST or None)
if form.is_valid():
form.instance.customer = request.user
form.save()
return redirect('tasks')
else:
form = TaskForm()
context = {'form':form}
return render(request,'todo_list/task_create.html',context)
Error:
ValueError at /create_task/
Cannot assign "<SimpleLazyObject: <User: Dominic>>": "Task.customer" must be a "Customer" instance.
I am trying to link the username in the user account to be shown on the model Task.customer that represents the post is created by that user. May I ask any methods could be done in order to specify the customer in the model Task? Also I do not understand the error message in detail because my admin panel already has the current username in the Customer model. However if I used request.user.customer the username does not show up instead returning None so how to solve this issue?
I don't know form.instance.customer = request.user
but I think I understood what you meant and the below code does the same thing
#login_required(login_url='login')
def taskCreate(request):
if request.method == 'POST':
form = TaskForm(request.POST or None)
if form.is_valid():
t = form.save(commit = False)
t.customer = request.user # assigning current user to created task.customer
t.save()
return redirect('tasks')
else:
form = TaskForm()
context = {'form':form}
return render(request,'todo_list/task_create.html',context)
if the code is still not working then try changing your line
customer = models.ForeignKey(Customer,on_delete=models.CASCADE,null=True) to
customer = models.ForeignKey(User,on_delete=models.CASCADE,null=True) in your models.py
The error comes from the following snippet
form.instance.customer = request.user
request.user is not a Customer instance, you can try extracting the information from request.user and create a Customer object from it and then assign it back
How can I rise the error and information, if user is puting only "dummy date" without "#"?
Email model is email = models.EmailField(max_length=254) but is only preventing passsing empty field, and nothing else. Can someone advice ?
def addContact(request):
form = ContactForm
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return redirect('/contact')
context = {'form': form}
return render(request, 'contact/new.html', context)
Forms:
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = '__all__'
Models:
class Contact(models.Model):
full_name = models.CharField(max_length=500)
relationship = models.CharField(max_length=50)
email = models.EmailField(max_length=254)
phone_number = models.CharField(max_length=20)
address = models.CharField(max_length=100)
def __str__(self):
return self.full_name
If you use EmailField then it has a built-in validator. Here is the code (https://docs.djangoproject.com/en/3.1/ref/validators/#emailvalidator)
You can use this validator to check the user input.
Here is the source code: https://docs.djangoproject.com/en/2.2/_modules/django/core/validators/#EmailValidator
I am trying to create an endpoint to edit both the user model and custom profile model below.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500)
location = models.CharField(max_length=50)
image = models.ImageField(default='default.jpg', upload_to='profile')
In the regular django I would do:
views.py
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
extended_profile_form = ProfileForm(request.POST,
request.FILES,
instance=request.user.profile)
if form.is_valid() and extended_profile_form.is_valid():
form.save()
extended_profile_form.save()
return redirect('accounts:profile')
else:
form = EditProfileForm(instance=request.user)
extended_profile_form = ProfileForm(instance=request.user.profile)
context = {
'form':form,
'extended_profile_form':extended_profile_form
}
return render(request, 'accounts/edit-profile.html', context)
what is the equivalent for django rest framework?
I have tried:
views.py (Django Rest Framework)
#api_view(['GET','PUT'])
def profile(request):
if request.method == 'GET':
user = User.objects.filter(username=request.user)
profile_user = Profile.objects.filter(user=request.user)
serializer_user = UserSerializer(user, many=True)
serializer_profile_user = ProfileSerializer(profile_user, many=True)
result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
return Response(result)
elif request.method == 'PUT':
user = User.objects.filter(username=request.user)
profile_user = Profile.objects.filter(user=request.user)
serializer_user = UserSerializer(user, data=request.data)
serializer_profile_user = ProfileSerializer(profile_user, data=request.data)
if serializer_user.is_valid() and serializer_profile_user.is_valid():
serializer_user.save()
serializer_profile_user.save()
result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
return Response(result)
result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
return Response(result.errors, status=status.HTTP_400_BAD_REQUEST)
When I am browsing the endpoint, it does display serializer_user and serializer_profile_user data but I am unable to edit any of those data using the DRF browsable API.
Am I right thinking the codes above is the equivalent of the codes from the codes from the normal django to edit the profile of the user?
It looks fine to me, but you need to replace this:
if request.method == 'GET':
user = User.objects.filter(username=request.user)
with this:
if request.method == 'GET':
try:
user = User.objects.get(id=request.user.id)
except User.DoesNotExist:
return Response(data='no such user!', status=status.HTTP_400_BAD_REQUEST)
# you need to use objects.get because objects.filter returns a queryset not an abject
Because, request.user is an instance of User model, you cannot compare it to an attribute of user (in your case username)
PS: same goes with your PUT method as well.
Hope this helps!
Look. You can make it easier. Let's take Post model (for example):
class Post(models.Model):
author = models.ForeignKey(base.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
text = models.TextField()
likes = models.ManyToManyField(base.AUTH_USER_MODEL, blank=True, related_name='post_likes')
created_date = models.DateTimeField(default=timezone.now)
And that You should describe it in your serializer (serializer is something similar to DTO. It converts data into a service-friendly JSON view):
class PostCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'text']
And the last part - Endpoint:
class PostUpdateView(UpdateAPIView):
serializer_class = PostCreateUpdateSerializer
def get_queryset(self):
return Post.objects.filter(author=self.request.user)
It will be more comfortable to use CBV for Django and DRF
And One more thing. You shouldn't create one more table for your user model. This is due to the extension of the BaseUser model. Link for help
I'm was creating ModelForm I try to make change the parent class while saving child class fields to the database, in the views.py I made but it didn't save to the database.
here is my model.py
class Table(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
book = models.BooleanField(default=False)
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
taple = models.OneToOneField(Table, on_delete=models.CASCADE, null=True, blank=True)
#receiver(post_save, sender=User)
def update_people_profile(sender, instance, created, **kwargs):
try:
instance.people.save()
except ObjectDoesNotExist:
People.objects.create(user=instance)
Class People is the child class and Table is the parent class so I'm using People class for making forms. here is my forms.py
class Booking(forms.ModelForm):
class Meta:
model = People
fields = [
'taple',
]
So I want to make True book field in Table class and save it to the database when saving Booking form. here is my views.py
def booking(request):
if request.method == 'POST':
try:
people_instance = People.objects.get(user=request.user)
except Table.DoesNotExist:
people_instance = People(user=request.user)
form = Booking(request.POST, instance=people_instance)
if form.is_valid():
user = form.save(commit=False)
user.taple.booking = True
user.refresh_from_db()
user.user = request.user
user.taple = form.cleaned_data.get('taple')
user.save()
print(user.taple.booking, user.taple.id)
return redirect('booked')
else:
form = Booking()
return render(request, 'main/booking.html', {'form': form})
Any Idea?
What I understand from the snippets is that you want to be able to record if a table is booked (book Boolean Field in your Table model and if so by whom, which is the object of your People model.
If my understanding is correct, then I don't think you really need a join table (People model). Instead, I would change your model as follow:
class Table(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
booked_by = models.OneToOneField(User, null=True, on_delete=models.SET_NULL, related_name='table_booked')
#property
def is_booked(self):
# This returns True if booked_by is set, False otherwise
return self.booked_by_id is not None
This way you don't need the People model. The property decorator will allow you to use is_booked as a calculated field.
Also, note the related name which will be used in the form:
class BookingForm(forms.ModelForm):
table_booked = forms.ModelChoiceField(queryset=Table.objects.filter(booked_by__isnull=True))
class Meta:
model = User
fields = ['table_booked',]
In the form, you will see that we define a custom queryset for table_booked. THe aim is to filter for free tables only.
Then you can hopefully simplify as well your view as follow:
Update:
As table_booked is a reverse foreign key, we actually need to save the table object which contains the relation. Here is the modified view:
#login_required
def booking(request):
form = BookingForm(request.POST or None, instance=request.user)
if form.is_valid():
user = form.save(commit=False)
tbl = form.cleaned_data['table_booked']
tbl.booked_by = request.user
tbl.save()
user.save()
print(request.user.table_booked.id, request.user.table_booked.is_booked)
return redirect('/')
return render(request, 'booking/booking.html', {'form': form})
Note: I haven't tested the code so there could be some typos but that should help you getting started.
I am currently trying to impliment a registration form but everytime I test it out, the new registrant replaces the old registration. So I am unable to have more than one user at a time.
any help would be great because I do not know what to do. Thanks.
My views:
def register_page(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
new_user = bitcoinUser(first_name=cd['first_name'],
last_name=cd['last_name'],
phone_number=cd['phone_number'])
new_user.save()
my models:
class bitcoinUser(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
phone_number = models.IntegerField(primary_key=True)
I honestly don't know why that didn't work (I think it is because you are saving the object 'new_user' and not the form), but i will recommend the way that i do forms in Django:
models.py:
from django.forms import ModelForm
class Bitcoinuser(models.Model):
first_name = models.CharField(max_length=36)
last_name = models.CharField(max_length=36)
phone = models.IntegerField(primary_key=True)
def __str__(self):
return self.name
class BitcoinuserForm(ModelForm):
class Meta:
model = Bitcoinuser
fields = ['first_name', 'last_name', 'phone']
views.py:
from .models import BitcoinuserForm
def get_bitcoinuser(request):
if request.method == 'POST':
form = BitcoinuserForm(request.POST)
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
phone = form.cleaned_data['phone']
form.save()
return HttpResponseRedirect('/database/')
else:
form = BitcoinuserForm()
return render(request, 'appname/get_bitcoinuser.html', {'form': form})
It's simple, straigthfoward and works fine.