How to overwrite Django Admin result_list? - python-3.x

Django newbie here..
I am working on a project that I need to do search in Django Admin Panel.
I have a model named SearchModel and it has colums named "id", "word" and an object called Desert and this object has '1' as id
I have another model named Result000 ('000' refers to the first three letters of md5 of "Desert" word). It has columns named "id", "word_id", "score", "title" and has an object named "Sahara Desert" whose word_id is the same as the id of the Desert object in the first table.
No ForeignKey or any other relation types between those table's items
here's the question:
When I search for Desert in SearchModel's search field. I want to list all objects in table Result000 which have word_id same as id of Desert object in SearchModel
here's my current code:
# root/admin.py
class BookAdmin(admin.ModelAdmin):
def __init__(self, model, admin_site):
self.list_display = [field.name for field in model._meta.fields]
self.search_fields = [field.name for field in model._meta.fields]
self.temp_model = "SearchModel"
self.temp_term = ""
self.word_id = None
self.search_term = self.temp_term
super().__init__(model, admin_site)
def get_search_results(self, request, queryset, search_term):
queryset, may_have_duplicate = super().get_search_results(
request, queryset, search_term
)
if len(search_term) > 0: self.search_term = search_term
else: self.search_term = self.temp_term
hashable, ret = self.md5_er(LowerTurkish(self.search_term).lower())
if hashable: table_name = f"Result{ret}"
else: table_name = request.path_info.split("/")[-2]
try:
# modelname = apps.get_model("root", table_name)
modelname = self.model_finder(table_name)
print("try içinde modelname: ", modelname)
messages.info(
request,
f"`{table_name}` modeli içindeki arama sonuçları")
word_id = self.model_finder(self.temp_model).objects.values_list("id")
std_content = modelname.objects.filter(word_id=word_id)
queryset = std_content
except:
std_content = self.model_finder(self.temp_model).objects.all()
# "nonetype not iterable" hatasının çözümü
return queryset, may_have_duplicate
def model_finder(self, table_name):
return apps.get_model("root", table_name)
def md5_er(self, data):
"""
:#params: data: md5 hashi alınacak olan veri, type: string
"""
hash_object = hashlib.md5(data.encode())
md5_hash = hash_object.hexdigest()
if md5_hash != "d41d8cd98f00b204e9800998ecf8427e":
"d41d8cd98f00b204e9800998ecf8427e refers md5 of empty string"
ret = md5_hash[:3]
return True, ret
else:
return False, False
I can get what I want if the SearchModel and Desert table have the same column names, but it doesn't work when the column names are changed. I've read almost all of Django's documentation, looked up examples from the internet, and looked at almost all entries on stackoverflow but as I said I'm Django newbie 🥲. Thanks in advance

Related

Showing Field Data On Another View

Thank You, trying to show the created_date field to the front table but i get an error, if i don't filter and use the all() method i am able to populate all the field data, but i would like to populate created_date field of member.I Get KEY ERROR "list_id"
class ListListView(ListView):
model = HBTYList
template_name = "accounts/modals/nomodal/index.html"
paginate_by = 3
def get_queryset(self):
qs = self.model.objects.all().order_by('-id')
p_f = HbtyCustomerListFilter(self.request.GET, queryset=qs)
return p_f.qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['dc'] = HBTYItem.objects.filter(hbty_cust_id=self.kwargs["list_id"]) #Fix this method to show created_data
context['filter'] = HbtyCustomerListFilter(self.request.GET, queryset=self.get_queryset())
return context

update a field in all records of a table through a single form Django 4

I have the following model 'ARTICULO', which I have created and templates to edit it individually
# MODEL
class Articulo(models.Model):
id = models.AutoField(primary_key=True, verbose_name='codigo')
nombre = models.CharField(max_length=100, verbose_name='nombre elemento')
cantidad = models.PositiveSmallIntegerField(verbose_name='cantidad total')
cantidad_disponible = models.PositiveSmallIntegerField(verbose_name='cantidad disponible', default=5)
UNIDAD = 'und'
KILO = 'kg'
LITRO = 'L'
UNIDADES_BASE = [
(UNIDAD, 'unidades'),
(KILO, 'Kilogramos'),
(LITRO, 'litros'),
]
unidades = models.CharField(max_length=3, choices=UNIDADES_BASE, default=UNIDAD, verbose_name='unidad base')
area = models.CharField(max_length=100, verbose_name='tipo inventario', default='primaria')
persona_asignada = models.CharField(max_length=100, default='almacen', verbose_name='persona asignada')
def __str__(self):
trama = "articulo: " + self.nombre
return trama
#form to edit individually
class ArticuloEditarForm(forms.ModelForm):
class Meta:
model = Articulo
fields = ['nombre', 'cantidad', 'unidades']
# view for generate form of individual article
def editar(request, id):
articulo = Articulo.objects.get(id=id)
formulario = ArticuloEditarForm(request.POST or None, instance=articulo)
if formulario.is_valid() and request.POST:
formulario.save()
return redirect('inventario_inicio')
return render(request, 'inventario/editar.html', {'formulario': formulario})
but additionally I would like to create a page where I can perform an update of all the records of the table as a whole (as in the following image)
When clicking on the button, all records with the checkbox activated are updated in the database according to the value indicated in their text box.
From what I have investigated so far, I think I understand that I should use the form.Form class and not form.ModelForm in combination with formsets, but in the attempts I have made, I tried trying to define a form in this way, but it does not work for me.
class AsignarReservasArticulos(forms.Form):
articulos = Articulo.objects.all()
for x in articulos:
print(x)
participa = forms.BooleanField(label='')
My deduction tells me that I must generate the form that I show in my image in an integral way from my FORM or I must make a part in the form and another in the view.

How to insert data to my DB when using another model's field in my form?

I have two different models: Trainer and User. I'm pulling in the trainer_price field from Trainer into my form in User. Please note that I'm also not using a foreign key.
The problem I'm having is that the trainer_price is not getting inserted and the default value of 0 is there, which is not what I want.
The way the User form works is they fill out their name, address, email and the trainer_price is automatically populated once they selected a trainer. It's also a read-only field.
Here's what I've tried so far:
user views.py
def buyer(request):
user_form = UserForm()
trainer_listing = Trainer.objects.get(id=15).trainer_price
context = {'user_form':user_form, 'trainer_listing':trainer_listing}
if request.method == "POST":
user_form = UserForm(request.POST)
if user_form.is_valid():
user_form.save()
return redirect("/success_page")
return render(request, "user/user_form.html", context)
forms.py
class UserForm(forms.ModelForm):
Fullname = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'John Doe'}))
Email = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Email'}))
Mobile = forms.CharField(widget=forms.TextInput(attrs={'placeholder': '312-222-2222'}))
Address = forms.CharField(widget=forms.TextInput(attrs={'placeholder': '1234 Main St'}))
City = forms.CharField()
State = forms.ChoiceField(choices=STATES)
zipcode = forms.CharField()
trainer_price = forms.DecimalField(label="Trainer Price", required=False, widget=forms.TextInput(attrs={'readonly':'readonly'}))
class Meta:
model = User
fields = ['Fullname','Email', 'Mobile', 'Address', 'City',
'State', 'zipcode', 'trainer_price']
Any help in the right direction would be great!
Basically, we can set default values for the form field using the initial argument.
def buyer(request):
trainer = Trainer.objects.get(id=15)
user_form = UserForm(initial={"trainer_price": trainer.trainer_price})
# etc
PS. Make sure that you do not populate the value from the trainer_price with the results from the request.POST. Smart users could use this to get very cheap deals. In stead, always re-query the actual value.

Combining Optional Passed query filters in Peewee

I am trying to Link a flask server to a Peewee database. I have a Rest GET request that passes data of the form
{'a':1,'b':2, 'filter':{'name':'Foo', 'count':3}}
I want to write a method that converts my filters into a database query and execute it to return their resource:
import datetime
import peewee as pw
import uuid
DATABASE = "Resources.db"
database = pw.SqliteDatabase(DATABASE)
class BaseModel(pw.Model):
class Meta:
database = database
class Resource(BaseModel):
name = pw.CharField(unique=True)
current_count = pw.IntegerField(default=1)
total_count = pw.IntegerField(default=1)
flavor = pw.CharField(default="undefined")
users = pw.TextField()
metadata = pw.TextField(default="")
is_avalible = pw.BooleanField(default=True)
uuid = pw.UUIDField(primary_key=True, default=uuid.uuid4)
max_reservation_time = pw.IntegerField(default=10)
def __str__(self):
return f"My name is {self.name} {vars(self)}"
This is kinda what my resource looks like. Here is what I am trying to do... (not a working full example)
def filter(filters):
for i,j in filters.items():
dq = Resource.select().where(getattr(Resource, i) == j)
for resource in dq:
print(resource)
if __name__ == "__main__":
try:
database.connect()
except pw.OperationalError:
print("Open Connection")
try:
create_tables()
except pw.OperationalError:
print("Resource table already exists!")
with database.atomic():
reso = Resource.create(name="Burns", current_count=4, total_count=5, users="Bar", blah=2)
filter({'name':"Burns","total_count":5})
Here I would expect to get back: My name is Burns {'__data__': {'uuid': UUID('80808e3a-4b10-47a5-9d4f-ff9ff9ca6f5c'), 'name': 'Burns', 'current_count': 4, 'total_count': 5, 'flavor': 'undefined', 'users': 'Grant', 'metadata': '', 'is_avalible': True, 'max_reservation_time': 10}, '_dirty': set(), '__rel__': {}}I believe I might be able to create individual peewee.expressions and join them some how, I just am not sure how.
Since peewee expressions can be arbitrarily combined using the builtin & and | operators, we'll use the reduce() function to combine the list using the given operand:
def filter(filters):
expression_list = [getattr(Resource, field) == value
for field, value in filters.items()]
# To combine all expressions with "AND":
anded_expr = reduce(operator.and_, expression_list)
# To combine all expressions with "OR":
ored_expr = reduce(operator.or_, expression_list)
# Then:
return Resource.select().where(anded_expr) # or, ored_expr
Thanks to #coleifer for the reminder. Here was my solution:
OP_MAP = {
"==": pw.OP.EQ,
"!=": pw.OP.NE,
">": pw.OP.GT,
"<": pw.OP.LT,
">=": pw.OP.GTE,
"<=": pw.OP.LTE,
}
def _generate_expressions(model, query_filter):
expressions = []
for expression in query_filter:
expressions.append(
pw.Expression(
getattr(model, expression["attr"]), OP_MAP[expression["op"]], expression["value"]
)
)
return expressions
def generate_query(model, query_data):
if query_data.get("filters") is None:
database_query = model.select()
else:
database_query = model.select().where(
*(_generate_expressions(model, query_data["filters"]))
)
return database_query
I pass the type of object I want to create an expression for and operator in the filter data. Iterating over the filters I can build the expressions and combine them.

How to Export Foreign Key Field to Excel In Django Views.py?

Getting this Error:- 'Restaurant' object has no attribute 'menu_here__starters'
I'm using Django-Excel Lib
In My Models.py
Class Restaurant(models.Model):
name = models.CharField(max_length=20)
area = models.CharField(max_length = 30)
menu_here = models.ForeignKey(Menu)
Class Menu(models.Model):
starters = models.CharField(max_length = 50)
desserts = models.CharField(max_length = 50)
In my Views.py
def download_excel_4(request):
query_set = Restaurant.objects.all() # Foreign column is Menu
column_names = ['menu_here__starters','menu_here__desserts' ]
return excel.make_response_from_query_sets(
query_set,
column_names,
'xls',
file_name="Restaurant With Complete Menu Database"
)
The make_response_from_query_sets takes the objects returned by query_set and displays it along with column names which should correspond with the field names of the objects.
The column_names acts like a filter displaying only the field names you want but it cannot further query after the objects are got. Therefore valid names are ['name', 'area', 'menu_here'].
An alternative would be to get objects as a dict with the related fields while querying using the .values() method and then using excel.make_response_from_records.
query_record = Restaurant.objects.all().values('name', 'area', 'menu_here__starters', 'menu_here__desserts')
return excel.make_response_from_records(
query_record,
'xls',
file_name="Restaurant With Complete Menu Database"
)

Resources