Django: Remove duplicate data - django

I am using Django and React for my app. I am really new in Django rest frame work. I have made three models, they are order, customer and products. Order models have many to one relationship with customers and products. I fetched the data successfully to React frontend. But the problem is when I make new entries, for example: when user order new product. It give each time same user's name is frontend like this. I checked some documentation and stackover-flow questions but did not find the right answers. I know i need do something in my views.py's Order query but don't know how.
This is my models
class Customer(models.Model):
name = models.CharField(max_length=200, null= True)
email = models.CharField(max_length=20, null=True)
phone = models.CharField(max_length=20, 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, blank= True)
date_created=models.DateTimeField(auto_now_add=True, null=True)
tags= models.ManyToManyField(Tag)
def __str__(self):
return self.name
class Order(models.Model):
STATUS =(
('Pending', 'Pending'),
('Out of delivery', 'Out of delivery'),
('Delivered', 'Delivered'),
)
status= models.CharField(max_length=200, null=True,choices= STATUS)
date_created=models.DateTimeField(auto_now_add=True, null=True)
customer = models.ForeignKey(Customer, null= True, on_delete= models.SET_NULL, related_name='orders')
product = models.ForeignKey(Product, null= True, on_delete= models.SET_NULL, related_name='orders')
This is my views.py
#api_view(['GET'])
def orderList(request):
orders = Order.objects.all()
serializer = OrderSerializer(orders, many=True)
return Response(serializer.data)
#api_view(['POST'])
def orderCreate(request):
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
#api_view(['GET'])
def customerList(request):
customers = Customer.objects.values_list('name', flat=True).distinct()
serializer = CustomerSerializer(customers, many=True)
return Response(serializer.data)
#api_view(['GET'])
def customerDetail(request, pk):
customers = Customer.objects.get(id=pk)
# orders = customers.order_set.all()
serializer = CustomerWithProductsSerializer(customers, many=False)
return Response(serializer.data)
This is my serializer
class OrderSerializer(serializers.ModelSerializer):
customer = CustomerSerializer()
product = ProductSerializer()
class Meta:
model = Order
fields = ['status', 'customer', 'product']

Related

Django select_related doesn't optimize query

I have a problem with select_related. I don't know what I'm doing wrong but it doesn't work..
models.py
class OrganizerUser(models.Model):
"""This user manage Agents"""
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.user.username
class Agent(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
organizer = models.ForeignKey(OrganizerUser, blank=True, null=True,
on_delete=models.CASCADE)
def __str__(self):
return self.user.username
class Lead(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
age = models.IntegerField(default=0)
organizer = models.ForeignKey(OrganizerUser, on_delete=models.CASCADE)
agent = models.ForeignKey(Agent, null=True, blank=True, on_delete=models.SET_NULL)
category = models.ForeignKey(
Category, related_name="categories", null=True, blank=True, on_delete=models.SET_NULL
)
description = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
phone_number = models.CharField(max_length=20)
email = models.EmailField()
converted_date = models.DateTimeField(null=True, blank=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
views.py
class LeadsApiView(generics.ListCreateAPIView):
serializer_class = LeadSerializer
permission_classes = [IsAuthenticated, IsAdminOrOrganizer]
def get_queryset(self):
user = self.request.user
#if user.is_staff:
#return Lead.objects.select_related('organizer', 'agent').all()
if user.is_organizer:
return Lead.objects.select_related('organizer').filter(
organizer=user.organizeruser)
else:
return Lead.objects.select_related('agent').filter(agent=user.agent)
serializers.py
class LeadSerializer(serializers.ModelSerializer):
class Meta:
model = Lead
fields = ['id', 'first_name', 'last_name', 'age',
'organizer', 'agent', 'category', 'description', 'date_added',
'phone_number', 'email', 'converted_date'
]
for agents everything is fine. Django makes 3 queries but for other users, it makes extra queries for each existing user.
This solution solved the problem
How to always prefetch_related for a specific django model
class UsersManager(models.Manager):
def get_queryset(self):
return super().get_queryset().select_related('user')
class OrganizerUser(models.Model):
"""This user manage Agents"""
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
objects = UsersManager()
def __str__(self):
return self.user.username
class Agent(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
organizer = models.ForeignKey(OrganizerUser, blank=True, null=True,
on_delete=models.CASCADE)
objects = UsersManager()
def __str__(self):
return self.user.username

Djnago Form getting Error while edit record

I am getting Issue while edit a record based on CHatquestion ID, if option is null then i need to add a record based on same chatquestion id, if chatqustion id exist in option it will work,
i am trying to multiple way to solve this issue but still can't find solution.
Models.py # thease are all 3 models
class Problem(models.Model):
Language = models.IntegerField(choices=Language_CHOICE, default=1)
type = models.CharField(max_length=500, null=True, blank=True)
def __str__(self):
return self.type
class ChatQuestion(models.Model): # Eding record based on chatquestion id
question = RichTextField(null=True, blank=True)
problem_id = models.ForeignKey(
Problem,
models.CASCADE,
verbose_name='Problem',
)
def __str__(self):
return self.question
is_first_question = models.BooleanField(default=False)
class Option(models.Model):
option_type = models.CharField(max_length=250, null=True, blank=True)
question_id = models.ForeignKey(
ChatQuestion,
models.CASCADE,
verbose_name='Question',
null=True,
blank=True
)
problem=models.ForeignKey(
Problem,
models.CASCADE,
verbose_name='Problem',
null=True,
blank=True
)
next_question_id = models.ForeignKey(ChatQuestion, on_delete=models.CASCADE, null=True, blank=True,
related_name='next_question')
def __str__(self):
return self.option_type
forms.py
class EditQuestionForm(forms.ModelForm):
class Meta:
model = ChatQuestion
fields =('question','problem_id')
class EditOptionForm(forms.ModelForm):
class Meta:
model = Option
fields =('option_type',)
views.py
def question_edit(request,id=None):
if id is not None:
queryset = get_object_or_404(ChatQuestion,pk=id)
queryset1=get_object_or_404(Option,question_id=queryset )
else:
queryset = None
queryset1 = None
if request.method=="POST":
form = EditQuestionForm(request.POST ,instance=queryset)
form1=EditOptionForm(request.POST, instance=queryset1)
if form.is_valid() and form1.is_valid():
question=form.cleaned_data['question']
option_type=form1.cleaned_data['option_type']
if id:
queryset.question=question
queryset.save()
queryset1.option_type=option_type
queryset1.save()
messages.success(request,'Sucessful')
return redirect('/fleet/list_chatbot')
else:
print(form.errors)
messages.error(request,'Please correct following',form.errors)
elif id:
form = EditQuestionForm(instance=queryset)
form1=EditOptionForm(instance=queryset1)
if not queryset1:
form1=EditOptionForm()
else:
form = EditQuestionForm()
form1=EditOptionForm()
context={
'form':form,
'form1':form1
}
return render(request,'chatbot/question_edit.html',context=context)

Custom "business" logic using pure Django

I am set on building a small website using django. What i am trying to do right now is using a CreateView based on a Model "Order", which one of its fields is another model "Customer".
The form itself works to create Orders, but im trying to find out how i can validate that the Customer that was selected is "enabled" (there is a status in the Customer model).
I was trying using the clean method but it doesnt even seem to be executing. I tried just raising the error on the clean, without validating anything, and still doesnt work. Any clue what might be wrong?
My Form:
class OrderForm(ModelForm):
def clean_customer(self, *args, **kwargs):
raise forms.ValidationError("This customer is banned.")
class Meta:
model = Order
fields = '__all__'
Relevant Models:
class Order(models.Model):
ORDER_STATUS = (('Pending Delivery', 'Pending Delivery'),
('Book on Customer', 'Book on Customer'),
('Overdue', 'Overdue'),
('Completed','Completed'))
customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)
book = models.ForeignKey(Book, null=True, on_delete=models.SET_NULL)
date_created = models.DateTimeField(auto_now_add=True)
date_due = models.DateTimeField(null=True)
date_completed = models.DateTimeField(null=True, blank=True)
status = models.CharField(max_length=100, choices=ORDER_STATUS, null=True)
def get_absolute_url(self):
return reverse('orders')
class Customer(models.Model):
status = models.CharField(max_length=10, null = True, choices=STATUS_CHOICES)
name = models.CharField(max_length=200, null=True)
username = models.CharField(max_length=25, null = True)
email = models.EmailField(null=True)
def __str__(self):
return str(self.name)+" - " +str(self.username)
def get_absolute_url(self):
return reverse('customers')
The View:
class OrderCreateView(CreateView):
model = Order
fields = '__all__'
def form_valid(self, form):
return super().form_valid(form)

Django DetailView filter by two parameters not using the primary key

I need to filter a model by two values that none of them is the PK of the model.
I want to filter the payments for an specific car and week, this means that I can have more than one payment for a car and in a week.
I'm using Django-Tables2 to display the results.
views.py
class PagosDetailView(SingleTableMixin, DetailView):
template_name = "AC/paymentsbycarandweek.html"
context_table_name = 'table'
model = Pagos
table_class = PagosTable
slug_url_kwarg = 'carro_id'
def get_queryset(self):
qs = super(PagosDetailView, self).get_queryset()
return qs.filter(carro=self.kwargs['carro'], semana=self.kwargs['semana'])
models.py
class Pagos(models.Model):
carro = models.ForeignKey(
Carros, on_delete=models.CASCADE, blank=False, null=False)
pago = models.DecimalField(max_digits=6, decimal_places=2)
fecha = models.DateField(
auto_now=False, auto_now_add=False, blank=True, null=True)
semana = models.CharField(max_length=20)
startweek = models.DateField(
auto_now=False, auto_now_add=False, blank=True, null=True)
endweek = models.DateField(
auto_now=False, auto_now_add=False, blank=True, null=True)
renta = models.ForeignKey(
Renta, on_delete=models.PROTECT, blank=False, null=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = "Pagos"
def get_absolute_url(self):
return reverse('pagos')
def __str__(self):
return self.semana
urls.py
path('paymentsbycarandweek/<int:carro>/<slug:semana>',
views.PagosDetailView.as_view(), name='pagos_bycar')
This last time that I have tried several options, I'm getting the following error message:
Generic detail view PagosDetailView must be called with either an object pk or a slug in the URLconf.
How exactly can I pass these two parameters?
After searching a lot, this is how I finally resolved it:
class PagosDetailView(SingleTableMixin, ListView):
model = Pagos
table_class = PagosDetailTable
template_name = 'AC/paymentsbycarandweek.html'
paginate_by = 10
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
self.object_list = self.object_list.filter(
carro=kwargs['carro'], semana=kwargs['semana'])
context = self.get_context_data()
return self.render_to_response(context)

How to load an instance in class based views using form_valid

I'm trying to build a form that automatically fills some fields in a class based create view that lets logged in users create a Job. However, I can't seem to find the correct way of doing this for fields that aren't the user (eg. request.user).
So the create view is trying to get a company_name from the logged in user, company_name field belongs to a model called Company. Each Company has an owner with a foreign key to the User model. All the reuest I've tried so far have led to a 'WSGIRequest' error.
So far I've tried to request:
company_name
user.company_name
company.company_name
company
user
I don't understand how these requests work, I have seen examples for getting the logged in users name and I'm not familiar how to do this otherwise.
Please can someone help me understand how this works and how I should be doing this?
I'm using Django 2.2 with python 3.6
Auth Models:
class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone_number = models.CharField(max_length=15)
email = models.EmailField(max_length=250, unique=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
objects = UserManager()
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
def __str__(self):
return self.first_name
def get_absolute_url(self):
return "/users/%i/" % self.pk
class Company(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
company_name = models.CharField(max_length=100, unique=True)
company_address = models.CharField(max_length=100, unique=True)
company_website = models.URLField(blank=True, null=True)
company_verified = models.BooleanField(default=False)
def __str__(self):
return self.company_name
View
class JobCreateView(LoginRequiredMixin, CreateView):
model = Job
form_class = JobForm
template_name = 'jobs/job_create.html'
def form_valid(self, form):
form.instance.company_name = self.request.user
form.instance.job_reference = self.request.job.pk
return super(JobCreateView, self).form_valid(form)
def get_success_url(self):
return reverse('jobs:job_details', kwargs={'pk': self.object.pk})
Other Model:
class Job(models.Model):
JOB_TYPE = (
('1', 'Service'),
('2', 'Repair'),
('3', 'Quotation'),
('4', 'Consultation'),
('5', 'Report'),
('6', 'Design'),
)
ACCOUNT_TYPE = (
('1', 'Existing Customer'),
('2', 'Charge to Account'),
('3', 'New Customer'),
('4', 'Pre-Paid/C.O.D'),
('5', 'Issued and Acc App'),
)
company_name = models.ForeignKey(Company, related_name='jobs', verbose_name="Company Name", on_delete=models.CASCADE)
job_reference = models.CharField(max_length=50, blank=False)
contact_person = models.CharField(max_length=50)
contact_number = models.IntegerField()
contact_person_email = models.EmailField(max_length=100, blank=True, null=True)
site_address = models.CharField(max_length=100)
job_type = models.CharField(choices=JOB_TYPE, max_length=50, default='1')
account_type = models.CharField(choices=ACCOUNT_TYPE, max_length=50, default='1')
job_details = models.CharField(max_length=1000)
created = models.DateTimeField(default=now, blank=True)
def __str__(self):
return str(self.company_name)
def get_absolute_url(self):
return reverse('jobs:detail', kwargs={'pk': self.pk})
For anyone trying to solve a problem like this, the answer is;
Views:
class JobDocketCreate(CreateView):
model = JobDocket
form_class = JobDocketForm
template_name = 'jobs/job_docket_create.html'
def form_valid(self, form):
form.instance.technician = self.request.user
form.instance.job = Job.objects.get(pk=self.kwargs['job_pk'])
print(form.instance.job)
print(form.instance.technician)
context = {'job_pk':self.kwargs['job_pk']}
return super(JobDocketCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(JobDocketCreate, self).get_context_data(**kwargs)
context['job_pk'] = self.kwargs['job_pk']
return context
def get_success_url(self):
return reverse('jobs:my_job_dockets')
Form action in View:
action="{% url 'jobs:create_job_docket' job_pk %}"