grepelli issue with autocomplete_search_fields - django

class DemoProvider(models.Model):
def __str__(self):
if self.MidName == None:
return u'%s, %s' % (self.LastName, self.FirstName)
else:
return u'%s, %s %s' % (self.LastName, self.FirstName, self.MidName)
PracticeName = models.ForeignKey('DemoPractice', on_delete=models.CASCADE)
FirstName = models.CharField(max_length=255, null=True, blank=True)
MidName = models.CharField(max_length=255, null=True, blank=True)
LastName = models.CharField(max_length=255, null=True, blank=True)
class Billing1500(models.Model):
Practice = models.ForeignKey('DemoPractice', on_delete=models.CASCADE)
Provider = models.ForeignKey('DemoProvider', on_delete=models.CASCADE)
PatiName = models.CharField(max_length=255, null=True, blank=True, help_text='Last Name, First Name')
PatiDOB = models.CharField(max_length=255, null=True, blank=True)
PatiSex = models.CharField(max_length=255, null=True, blank=True)
#staticmethod
def autocomplete_search_fields():
return ("Provider_icontains", )
#admin.register(Billing1500)
class Billing1500(admin.ModelAdmin):
raw_id_fields = ('Provider',)
autocomplete_lookup_fields = {
'fk': ['Provider'],
}
pass
i'm trying to have autocomplete search fields in my grapellie admin models, however im getting errors when trying to bind my foreignkeys to my grappelli function. i'm having the following issue
ERRORS:
?: (grappelli.E001) Model Core.billing1500 returned bad entries for autocomplete_search_fields: Provider_icontains
HINT: A QuerySet for {model} could not be constructed. Fix the autocomplete_search_fields on it to return valid lookups.
reading the docs it looks like what I have should be correct no?

Related

Django: Filter on model column with Regex

I have phone numbers stored as (921) 414-1313 in the database and I want to run a search lookup on that field, but I don't want to force them to include (, ' ', ) or -.
I'm using Postgres and tried to work with SearchVector initially, however it ran into the same challenge (so for now, I'm doing it the old fashioned way).
I have a model definition that returns an "unformatted" number as 9214141313, but I can't figure out how to query against my custom definition inside of the model?
Ultimately, I want a customer to be able to type in 921414 and get the response for the matching record.
GitHub:
https://github.com/varlenthegray/wcadmin/blob/dev/main/views.py#L25
Model:
class JobSite(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
quickbooks_id = models.IntegerField(editable=False, null=True, blank=True)
name = models.CharField(max_length=200, null=True, blank=True)
first_name = models.CharField(max_length=200, null=True, blank=True)
last_name = models.CharField(max_length=200, null=True, blank=True)
print_on_check_name = models.CharField(max_length=200, null=True, blank=True)
address = models.CharField(max_length=200, null=True, blank=True)
address_2 = models.CharField(max_length=200, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
state = models.CharField(max_length=50, null=True, blank=True)
zip = models.CharField(max_length=20, null=True, blank=True)
phone_number = models.CharField(max_length=30, null=True, blank=True)
email = models.CharField(max_length=400, null=True, blank=True)
service_interval = models.IntegerField(default=12)
next_service_date = models.DateField(null=True, blank=True)
primary_technician = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
active = models.BooleanField(default=True)
access_code = models.CharField(max_length=10, null=True, blank=True)
bill_parent = models.BooleanField(default=False)
requires_supporting_technician = models.BooleanField(default=False)
service_scheduled = models.BooleanField(default=False)
disable_service = models.BooleanField(default=False)
qb_created_on = models.DateTimeField(null=True, blank=True)
def __str__(self):
return f'{self.name}'
def phone_digits_only(self):
return re.sub("[^0-9]", "", self.phone_number)
#property
def is_past_due(self):
ignore_after = timezone.localdate() - relativedelta(years=5)
# noinspection StrFormat
if self.next_service_date:
if ignore_after >= self.next_service_date:
return False
else:
return timezone.localdate() > self.next_service_date
else:
return False
#property
def is_due_soon(self):
ignore_after = timezone.localdate() - relativedelta(years=3)
if self.next_service_date and self.next_service_date >= ignore_after:
three_months_future = timezone.localdate() + relativedelta(months=2)
return three_months_future > self.next_service_date
else:
return False
Views.py
def search_system(request, search_term=False):
if search_term:
job_sites = JobSite.objects.filter(
Q(first_name__icontains=search_term) |
Q(last_name__icontains=search_term) |
Q(quickbooks_id__icontains=search_term) |
Q(email__icontains=search_term) |
Q(phone_number_digits=search_term)
)
else:
job_sites = JobSite.objects.all().prefetch_related('customer')
data = []
for job in job_sites:
if job.first_name and job.last_name:
name = job.first_name + ' ' + job.last_name
elif job.customer.company:
name = job.customer.company
else:
name = job.customer.first_name + ' ' + job.customer.last_name
this_job = {'value': name}
data.append(this_job)
return JsonResponse(data, safe=False)
The best solution IMHO is to use the library phonenumbers which is very cleaned and well maintained.
Then do a custom "phone_cleaned" field where you add the signals "create" and "update" for this model, and update phone_cleaned accordingly (using the library to clean the phone number). And use that phone_cleaned to do all your searches.

Return all the orderitems in an order of a customer Django

I want to return all the items in all the orders that have made a customer.
I don't know if it is possible or how I need to do it, I tried to get the orders with .get and .filter in my views but with get is only possible to return one value
My models.py
class Customer(models.Model):
user = models.OneToOneField(Account, on_delete=models.CASCADE, null=True)
first_name = models.CharField(max_length=200, null=True)
last_name = models.CharField(max_length=200, null=True, blank=True)
phone = models.CharField(max_length=10, null=True, blank=True)
email = models.EmailField(null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return str(self.user)
class Category(models.Model):
name = models.CharField(max_length=200, null=True)
class Meta:
verbose_name='categoria'
verbose_name_plural ='categorias'
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=200, null=True)
price = models.FloatField(null=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
description = models.TextField(max_length=500, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
ventas = models.IntegerField(null=True, blank=True, default=0)
image = models.ImageField(null=True, blank=True, default='Banner_Cubrebocas.png')
def __str__(self):
return self.name
class Order(models.Model):
STATUS= (
('Pending', 'Pending'),
('Delivered', 'Delivered')
)
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
#product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True, blank=True)
date_created =models.DateTimeField(auto_now_add=True, null=True)
status = models.CharField(max_length=200, null=True, choices=STATUS, default='Pending')
complete = models.BooleanField(default=False, null=True, blank=True)
def __str__(self):
return str(self.id)
#property
def shipping(self):
shipping= False
orderitems=self.orderitem_set.all()
for i in orderitems:
if i.product.digital == False:
shipping=True
return shipping
#property
def get_cart_total(self):
orderitems= self.orderitem_set.all()
total= sum([item.get_total for item in orderitems])
return total
#property
def get_cart_items(self):
orderitems= self.orderitem_set.all()
total= sum([item.quantity for item in orderitems])
return total
class OrderItem(models.Model):
product= models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order= models.ForeignKey(Order, on_delete=models.CASCADE, null=True)
quantity= models.IntegerField(default=0, null=True, blank=True)
date_added= models.DateTimeField(auto_now=True, null=True)
and my views.py I tried with different foms but I don't get the correct one
def customer(request, pk_test):
qs = Product.objects.all()
category_query = request.GET.get('category')
status_query = request.GET.get('status')
customer = Customer.objects.get(id=pk_test)
orders= customer.order_set.all()
orders_count = orders.count()
order = Order.objects.filter(customer__id=pk_test, complete=False)
items = order.orderitem_set.all()
#myFilter= OrderFilter(request.GET, queryset=orders)
#orders = myFilter.qs
categories = Category.objects.all()
if status_query != '' and status_query is not None:
items = items.filter(order__status__icontains=status_query)
if status_query == 'All status':
items = order.orderitem_set.all()
context = {
'customer':customer,
'orders':orders,
'orders_count':orders_count,
#'myFilter':myFilter,
'categories':categories,
'order':order,
'items':items,
}
return render(request, 'cuentas/customer.html', context)

business generated has to come based on dcr(daily call report)

I have DCR & SalesMIS model. I want to get the business generated count. And if count is it should return the business_genrated else saleMIS.amount
I wrote a method in DCR model i.e. get_business_generated(self) and apply filter on SaleMIS model. Then trying to get the count of business_generated
ERROR:D:\Projects\Python\Django\kingllp\venv\lib\site-packages\django\db\models\base.py", line 95, in new
"INSTALLED_APPS." % (module, name)
RuntimeError: Model class builtins.DCR doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
This is DCR model
class DCR(models.Model):
STATUSES = (
('1N', 'Need Analysis'),
('2P', 'Proposal Stage'),
('3C', 'Competitive Selling'),
('4D', 'Decision Stage'),
)
prospect = models.ForeignKey(Prospect, on_delete=models.CASCADE, related_name='dcrs')
date = models.DateField(blank=True)
status = models.CharField(choices=STATUSES, max_length=2, default='1N')
discussion_points = models.CharField(max_length=2047, blank=True)
business_generated = models.IntegerField(default=0)
is_new_business = models.BooleanField(default=False)
def get_business_generated(self):
date = self.date
client = self.prospect
sale = SalesMIS.objects.filter(date=date,client = Prospect)
salecount = sale.count()
if salecount==0:
return DCR.business_generated
else:
return SalesMIS.amount
This is SaleMIS model
class SalesMIS(models.Model):
class Meta:
verbose_name_plural = _("Sale MIS")
date = models.DateField()
fls = models.ForeignKey(Employee, blank=True, null=True, on_delete=models.SET_NULL, related_name='sales')
amount = models.DecimalField(max_digits=20, decimal_places=2)
po_number = models.CharField(max_length=255, null=True, blank=True)
products = models.CharField(max_length=255, null=True, blank=True)
client = models.ForeignKey(Client, blank=True, null=True, on_delete=models.SET_NULL, related_name='client_mis')
def __str__(self):
return str(self.date) + ":" + self.fls.full_name()
Business share has to come based on DCR/MIS.

Auto Complete field in django

here are my models
class TimeSlots(models.Model):
start = models.TimeField(null=True, blank=True)
end = models.TimeField(null=True, blank=True)
class Meta:
ordering = ['start']
def __str__(self):
return '%s - %s' % (self.start, self.end)
class Event(models.Model):
event_date = models.DateField(null=False, blank=True)
start = models.OneToOneField(TimeSlots)
end = models.TimeField(null=True, blank=True)
available = models.BooleanField(default=True)
patient_name = models.CharField(max_length=60, null=True, blank=True)
phone_number = PhoneNumberField(blank=True, null=True)
stripePaymentId = models.CharField(max_length=150, null=True, blank=True)
stripePaid = models.BooleanField(null=False, blank=True, default=True)
key = models.UUIDField(primary_key=False, default=uuid.uuid4,
editable=False)
sites = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
verbose_name = u'Scheduling'
verbose_name_plural = u'Scheduling'
def __unicode__(self):
return self.start
def get_absolute_url(self):
url = reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[self.pk])
return u'%s' % (url, str(self.start))
What I want is that end value of Event Model should be auto filled by the selected Timeslot
like when I choose a start value from timeslot for the event model the end value should automatically be filled
Ok I solved it by adding a clean function in my model
def clean(self):
self.end = self.start.end
It was that simple

Add extra column to tables in django_tables2

I want to add extra-column which is not in my model. And I apply one of the solutions at this site to my project. But it doesn't work properly.
model.py
class Companies(models.Model):
legal_name = models.CharField(max_length=120, blank=True)
co_name = models.CharField(max_length=120, blank=True)
client = models.ForeignKey(Clients, models.SET_NULL, blank=True, null=True)
tel_no = models.CharField(max_length=120, blank=True)
email = models.EmailField(null=True, blank=True)
address = models.TextField(null=True, blank=True)
contact = models.CharField(max_length=250, blank=True)
con_tel_no = models.CharField(max_length=120, blank=True)
entity = models.CharField(max_length=2, null=True)
yearend = models.DateField(null=True, blank=True)
bn = models.CharField(max_length=9)
memo = models.TextField(null=True, blank=True)
slug = models.SlugField(null=True, blank=True)
def t2_due_date(self):
now_year = datetime.date.today().year
if self.entity == 'CO':
yearend_ = DateWidget.decompress(self, self.yearend)
if yearend_[1] > 6:
yearend_[2] = now_year + 1
yearend_[1] -= 6
else:
yearend_[2] = now_year
yearend_[1] += 6
t2_due = DateWidget.compress(self, yearend_)
return t2_due
tables.py
class ScheduleTable(tables.Table):
due_date_col = tables.Column(accessor='t2_due_date', verbose_name='T2 Due Date')
class Meta:
attrs = {"class": "paleblue", "width":"100%"}
fields = ['client','legal_name', 'co_name', 'entity', 'yearend', 'due_date_col']
model = Companies
When I run this program 'due_date_col' is always blank. It seems that the function('t2_due_date) does not go through. Do you have any clue to clear this problem?
As far as I know accessor points to related objects, rather than model's properties, methods etc.
What you can try is to make use of Table.render_{column} as so:
class ScheduleTable(tables.Table):
def render_due_date_col(self, record):
return record.t2_due_date()
See djanog tables official doc for more info.