How to assign a customer to a user in Django? - python

I created a system and in this system, there are several users and customers. What I want to create an assign function. A customer should assign to a user.
For example, I have a customer list. When the user clicks a button, the user will see a list that other users and select one of them. After that, the customer's name will be listed in the different assigned customers list of the selected user.
I wrote a code and this is working, but I cannot reach user from customer list. What I mean is when I click assign button it create a new customer. How can I reach user id or username?
views.py
def customer_list(request):
current_user = request.user
userP = UserProfile.objects.get_or_create(username=current_user)
customer_list = Customer.objects.filter(company=userP[0].company.comp_name)
# Assign
form = AssignForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('user:customer_list')
myFilter = TableFilter(request.GET, queryset=customer_list.all())
context = {
'customer_list': customer_list,
'myFilter': myFilter,
'form': form
}
return render(request, 'customer_list.html', context)
models.py
class Customer(models.Model):
customer_name = models.CharField(max_length=20)
country = models.CharField(max_length=20)
address = models.CharField(max_length=100)
VATnumber = models.CharField(max_length=10)
telephone = models.CharField(max_length=10)
email = models.CharField(max_length=30)
contact_person = models.CharField(max_length=30)
company = models.CharField(max_length=20)
id = models.AutoField(primary_key=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, blank=True, null=True)
class UserProfile(AbstractUser, UserMixin):
company = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True, unique=False)
user_id = models.UUIDField(default=uuid.uuid4(), editable=False, unique=True)
username = models.CharField(max_length=500, unique=True)
first_name = models.CharField(max_length=200)
customer_list.py
<table id="multi-filter-select" class="display table table-striped table-hover grid_" >
<thead>
<tr>
<th>Customer Name</th>
<th>Country</th>
<th>E-Mail</th>
<th>Phone</th>
<th>VAT Number</th>
<th>Operations</th>
</tr>
</thead>
<tbody>
{% for customer in customer_list %}
<tr>
<td>{{customer.customer_name}}</td>
<td>{{customer.country}}</td>
<td>{{customer.email}}</td>
<td>{{customer.telephone}}</td>
<td>{{customer.VATnumber}}</td>
<td>
<div class="row">
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#demo{{ forloop.counter }}">Assign</button>
<div id="demo{{ forloop.counter }}" class="collapse">
{% if customer.user == null %}
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-success ">Assign</button>
</form>
{% else %}
Assigned to {{ customer.user.first_name }} {{ customer.user.last_name }}
{% endif %}
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
forms.py
class AssignForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('user',)

views.py
def customer_list(request):
current_user = request.user
userP = UserProfile.objects.get_or_create(username=current_user)
customer_list = Customer.objects.filter(company=userP[0].company.comp_name)
# Assign
form = AssignForm(request.POST or None)
if request.POST:
customer_id = request.POST.get('customer_id', None)
customer = Customer.objects.get(id=customer_id)
user = UserProfile.objects.get(id=request.POST.get('user', None))
customer.user = user
customer.save()
form.save()
return redirect('user:customer_list')
context = {
'customer_list': customer_list,
'form': form
}
return render(request, 'customer_list.html', context)
customer_list.html
...
<button type="button" class="btn btn-success" data-toggle="collapse" data-target="#demo{{ forloop.counter }}">Assigned</button>
...
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<input type="hidden" name="customer_id" value="{{ customer.id }}">
<button type="submit" class="btn btn-success ">Assign</button>
</form>

Related

Use CreateView and ListView in the same template and use form.instance correctly

In my project my user should be able to submit an appointment (class UserAppointment) based on the responsibility given by the staff (class StaffDuty). So I'd like to use the CreateView class of the UserAppointment model and ListView class for the StaffDuty model in the same template. With my code I can access the data from the StaffDuty model but I'm not able to submit the form for UserAppointment model, since the submit button does nothing.
Also I'd like to automatically assign the staff and event foreign key and pass data from StaffDuty to complete form.instance.date_appointment with the date given in the staff model and form.instance.event_name with the name of the event that is found in the Event model. But my code is not working at all
models.py
class Event(models.Model):
name = models.CharField(max_length=255)
staff_needed = models.PositiveIntegerField()
date = models.DateField()
spots_total = models.PositiveIntegerField()
venue = models.CharField(max_length=255)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('event_details', args=[str(self.id)])
class StaffDuty(models.Model):
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
date_work = models.DateField()
shift = models.CharField(max_length=255)
def __str__(self):
return self.event.name | str(self.date_work)
class UserAppointment(models.Model):
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
staff = models.ForeignKey(StaffDuty, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
event_name = models.CharField(max_length=255)
date_appointment = models.DateField(null=True)
morning_hour = models.CharField(max_length=255)
afternoon_hour = models.CharField(max_length=255)
spots_free = models.PositiveIntegerField(null=True)
def __str__(self):
return self.event.name | str(self.staff.date_work)
def get_absolute_url(self):
return reverse('home')
views.py
class StaffDutyAddView(CreateView):
model = StaffDuty
form_class = StaffDutyForm
template_name = 'reservation.html'
success_url = reverse_lazy('home')
class UserAppointmentAddView(CreateView):
model = UserAppointment
form_class = UserAppointmentForm
template_name = "reservation.html"
def form_valid(self, form):
form.instance.user = self.request.user.userinformation
# Code incomplete and that not work
form.instance.staff = StaffDuty.objects.filter(user=self.request.user.staffduty).first()
#form.instance.date_appointment = # add date_work from StaffDuty class
form.instance.event = Event.objects.filter(user=self.request.user.event).first()
#form.instance.event_name = # add name of the event from Event class
return super(UserAppointmentAddView, self).form_valid(form)
def get_context_data(self, **kwargs):
kwargs['object_list'] = StaffDuty.objects.order_by('id')
return super(UserAppointmentAddView, self).get_context_data(**kwargs)
html
<div class="container">
{% for appointment in object_list %}
<tbody>
<tr class="inner-box">
<th scope="row">
<div class="event-date">
</div>
</th>
<td>
<div class="event-img">
{% if appointment.id_image %}
<img src="#" alt="">
{% endif %}
<p>{{ appointment.event}}</p>
</div>
</td>
<td>
<div class="event-wrap">
<h3>{{ appointment.get_shift_display }}</h3>
<div class="time">
<span>{{ form.staff }}</span>
<span>{{ form.event }}</span>
<span>{{ form.morning_hour }}</span>
<span>{{ form.afternoon_hour }}</span>
</div>
</div>
</div>
</td>
<td>
<div class="r-no">
<span> {{ appointment.spots_free }}/{{ appointment.event.spots_total }}</span>
</div>
</td>
<td>
<div class="r-no">
<span>{{ appointment.event.venue }}</span>
</div>
</td>
<td>
<div class="primary-btn">
<input type="submit" value="submit" class="btn btn-primary">
</div>
</td>
</tr>
</tbody>
{% endfor %}
P.s (I had to change my code a little to make it shorter and more clear. They may be typo that are not in my original code)

forms in Django does not register the data in the database

I'm stuck I try a lot of things to make it work, but always the same problem the form dose note save the data at all
and the any error that I get is the message error (what I writ in the message)
all i get is a change in the url like this
http://127.0.0.1:8000/appointement/create_appointement_2?patient=patient+12&initial-patient=patient+12&doctor=2&date=2021-04-02&start_time=16%3A30
is there anything that can show me the error or if anyone have this problem be for a few hits will be awesome?
this is my models .py
class Appointment(models.Model):
user_ho_add = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_ho_add_appointment')
patient = models.CharField(null=True,max_length = 200, default=defaultTitle)
doctor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='doctor_app')
date = models.DateField(null=False, blank=False, default=timezone.now)
start_time = models.TimeField(null=True, blank=True, default=timezone.now)
end_time = models.TimeField(null=True, blank=True, default=timezone.now)
and this is my forms.py
class AppointmentForm_2(forms.ModelForm):
doctor = forms.ModelChoiceField(queryset=User.objects.filter(type_of_user=TypeOfUser.DOCTOR))
# patient = forms.ModelChoiceField(queryset=User.objects.filter(type_of_user=TypeOfUser.PATIENT))
date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), input_formats=settings.DATE_INPUT_FORMATS)
start_time = forms.DateField(widget=forms.DateInput(attrs={'type': 'time'}), input_formats=settings.TIME_INPUT_FORMATS)
class Meta:
model = Appointment
fields = ('patient', 'doctor', 'date', 'start_time')
and this is the views.py
#login_required
def create_appointement_2(request):
user = get_user_model()
patients = User.objects.filter(type_of_user=TypeOfUser.PATIENT)
form_appointment_2 = AppointmentForm_2(request.POST or None)
if request.user.is_doctor() or request.user.is_reception():
if request.method=='POST':
form_appointment_2 = AppointmentForm_2(request.POST or None)
user = get_user_model()
if form_appointment_2.is_valid():
form_appointment_2.save(commit=False)
form_appointment_2.user_ho_add = request.user
# form_appointment.end_time = form_appointment.start_time + timedelta(minutes=30)
start_time = form_appointment_2.start_time
future_time = dt.datetime(1970, 1, 1, start_time.hour, start_time.minute, start_time.second, start_time.microsecond) + timedelta(minutes=30)
form_appointment_2.end_time = dt.time(future_time.hour, future_time.minute, future_time.second, future_time.microsecond)
form_appointment_2.save()
messages.success(request, 'appointment added')
else:
messages.error(request, 'Error')
else:
return render(request, 'appointement/add_appointement2.html', {'user_form':form_appointment_2,'patients':patients })
return render(request, 'appointement/add_appointement2.html', {'user_form':form_appointment_2,'patients':patients })
and this the html file
<body>
{% if form.errors %}
<div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">
<div id="form_errors">
{% for key, value in form.errors.items %}
<span class="fieldWrapper">
{{ key }}:{{ value }}
</span> {% endfor %}
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
<div class="container">
<form>
{{ user_form.media }} {{ user_form }} {% csrf_token %}
<button type="submit" value="create_appointment">
ok
</button>
</form>
</div>
</body>
I try to add the error tag, but it shows nothing, all i get is a change in the url like this
http://127.0.0.1:8000/appointement/create_appointement_2?patient=patient+12&initial-patient=patient+12&doctor=2&date=2021-04-02&start_time=16%3A30
if you are getting the data in the url that means you need to add method="POST" to your form tag in the html file

Django Templates Formsets with Foreign Key Lookup

hoping for some guidance around my below problem with displaying reverse lookup field in a template inside formsets.
Maintenance Item Model
class Maintenance_Item(CommonInfo):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, unique=True)
name_description = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
Checklist Model
class MaintenanceCheckList(CommonInfo):
CHOICES = (
('P','Compliant'),
('F','Non-Compliant'),
)
id = models.AutoField(primary_key=True)
item = models.ForeignKey(Maintenance_Item, on_delete=PROTECT, related_name='item_name')
is_compliant = models.CharField(max_length=20, choices= CHOICES, default=CHOICES[0][0])
def __int__(self):
return self.item
EDIT Form
class MaintenanceCheckListComplianceForm(forms.ModelForm):
is_compliant = forms.ChoiceField(
choices=MaintenanceCheckList.CHOICES,
widget=forms.RadioSelect,
required=False,
)
class Meta:
model = MaintenanceCheckList
fields = ('item','is_compliant',)
END EDIT
The current template
<form class="" method='post'>
{% csrf_token %}
{{ form.management_form }}
<table class="table my-0" id="dataTable">
<thead>
<tr>
<th>Maintenance Items</th>
</tr>
</thead>
<tbody>
{% for sub_form in form %}
<tr>
{% for i in sub_form.item_name.all %}
<td>Item: {{ i.name }}</p>
{% endfor %}
{{ sub_form.item|add_class:"form-select" }}<p>
</p>{{ sub_form.is_compliant }}</td>
</tr>
{% endfor %}
</table>
<div class="divider"></div>
<div class="col-md-12">
<p class='pt-sm-2'>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Currently, I have generic formset view which creates an row for each item in the Maintenance_Item which works brilliant and generates the formset view as shown.
The challenge, I have is I want to hide the ModelChoice fields (I can do that easily with a Widget), and just display the friendly name in the ModelChoice field as a simple Text Label in the template.
Note setting disabled won't work because POST ignores disabled fields (already troubleshooted using that)

How to update multiple objects with one form in Django?

I create a customer model and a function for assign a customer to a user. Assign function is update user field in Customer model.
This Customer model has a country field. I want to assign the customers in the same country to a user with one form. For doing that I have listing all countries and a form for assign operation? How can I do that?
Edit: Now, I can get country name and the user for assigning. How can I use these attributes and update the objects (Customer) with chosen country and user.
models.py
class Customer(models.Model):
customer_name = models.CharField(max_length=20)
country = models.ForeignKey(Country, on_delete=models.CASCADE, null=True, unique=False)
...
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, blank=True, null=True)
class Country(models.Model):
REGION = [
('Northwest Europe', 'Northwest Europe'),
('Southwest Europe', 'Southwest Europe'),
...
]
country_name = models.CharField(max_length=30)
country_code = models.CharField(max_length=5)
views.py
def country_customer_list(request):
current_user = request.user
userP = UserProfile.objects.get_or_create(username=current_user)
customer_list = Customer.objects.filter(company=userP[0].company)
countries = Customer.objects.values_list('country__country_name', flat=True).distinct()
form = CountryForm(request.POST or None)
if request.POST:
country_form = request.POST.get('country_form', None)
user = request.POST.get('user', None)
form.save()
print(country_form)
print(user)
return redirect('user:customer_countries')
context = {
'customer_list': customer_list,
'countries': countries,
'form': form
}
return render(request, 'country_customer_list.html', context)
country_customer_list.html*
<table id="multi-filter-select" class="display table table-striped table-hover grid_" >
<thead>
<tr>
<th>Country</th>
<th>Operations</th>
</tr>
</thead>
<tbody>
{% for country in countries %}
<tr>
<td>{{country}}</td>
<td>
<button type="button" class="btn btn-info btn-block" data-toggle="collapse" data-target="#demo{{ forloop.counter }}"> Assign </button>
<div id="demo{{ forloop.counter }}" class="collapse">
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<input type="hidden" name="country_form" value="{{ country }}">
<button type="submit" class="btn btn-primary btn-sm">Assign</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
forms.py
class CountryForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('user',)
Populate Country models with your choise, and they will appear in the template
Change models
class Country(models.Model):
country_name = models.CharField(max_length=30)
country_code = models.CharField(max_length=5)
def __str__(self):
return str(self.country_name) + ' ' + str(self.country_code)
forms.py
class CountryForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('user','country',)
in template
{{form.country}}

how to display specific results from the dropdown in models.py in django

I want to display only employees which emp_type is 'Doctor'?
** Here is Models.py **
class Employee(models.Model):
name = models.CharField(max_length=50)
emp_type_choices = [
('Nurse', 'Nurse'),
('Doctor', 'Doctor'),
('Other', 'Other'),
]
emp_type = models.CharField(
max_length=6, choices=emp_type_choices, default='Nurse')
def __str__(self):
return self.name
class Ticket(models.Model):
patient = models.CharField(max_length=50)
doctor = models.ForeignKey(Employee, on_delete=models.CASCADE)
def __str__(self):
return self.patient.name
This is my Forms.py
class TicketModelForm(forms.ModelForm):
class Meta:
model = Ticket
fields = ['doctor', 'status']
widgets = {
'doctor': forms.Select(attrs={'class': 'form-control','placeholder': 'Doctor Name'}),
}
This is my Views.py
#login_required
def TicketToGenerateView(request, pk):
ticket = get_object_or_404(Patient, pk=pk)
form = TicketModelForm(request.POST or None)
if form.is_valid():
obj.save()
return redirect('/dashboard/ticket')
context = {
'form': form,
'ticket': ticket,
}
return render(request, 'dashboard/ticket.html', context)
This is my Template
<form action="." method="POST">
{% csrf_token %}.
{% for field in form %}
<div class="form-group">
{{ field }}
{% if field.errors %}
{% for error in field.errors %}
<p class="text-danger">{{ error|escape }}</p>
{% endfor %}
{% endif %}
</div>
{% endfor %}
<div class="form-group float-right">
<button type="submit" class="btn btn-success btn-sm" value=" {{ valueBtn }} "> <span
class="glyphicon glyphicon-plus"></span> </button>
</div>
</form>
In the template, I'm displaying all registered employees as a dropdown list, but I would like to display only employees which their emp_type is 'Doctor'.
Also the Admin site I would like to see the only emp_type which are 'Doctor'.
Thanks
# You have to use filter for your query
emp_doctor = Employee.objects.filter(emp_type='Doctor')
print(emp_doctor)

Categories