Change add button django admin if data filtrin - django

I new her and need help
I create a few models:
Customer
Orders
How to make the ADD button dynamic
If I use a filter and my url is http://127.0.0.1:8000/admin/catalog/order/?order_customer__id=3, in this case pass the following value to the button <a href="{% url opts|admin_urlname:'add ' %}?order_customer={{cl.result_list.0.order_customer.id}}"
To prompt you to fill out the form when creating a new record. Accordingly, the url should look like this
http://127.0.0.1:8000/admin/catalog/order/add/?order_customer=3
If the filter is missing url http://127.0.0.1:8000/admin/catalog/order/, the button has a default value
Accordingly, when switching to the creation form, the url has a standard value
http://127.0.0.1:8000/admin/catalog/order/add
Django 3.2.6
addons smart_selects
models.py
class Customer(models.Model):
"""docstring for Customer."""
customer_name = models.CharField(max_length=200, verbose_name='Назва юридичної особи/ФОП', help_text='Введіть поністю назву юридичної особи чи фізичної особи підприємця')
customer_inn = models.CharField(max_length=15, verbose_name='ЄДРПОУ', help_text='Введеіть ЄДРПОУ для юридичної особи чи ідентифікаційний код для ФОП')
customer_adress = models.TextField(max_length=200, verbose_name='Юридична адреса клієнта' , help_text='Притриймуйтесь формату аналогічно витягу ЄДР. Наприклад: 79000, Область, Район, Місто/Селище, вулиця/проспект Назва вулиці, Номебр будинку, квартира')
customer_ceo = models.CharField(max_length=50, verbose_name='Керівник/підписант')
class Meta:
verbose_name = 'Клієнт'
verbose_name_plural = 'Клієнти'
def __str__(self):
"""
String for representing the Model object.
"""
return self.customer_name
class Order(models.Model):
order_customer = models.ForeignKey('Customer', on_delete=models.CASCADE, verbose_name="Клієнт")
order_date = models.DateField(verbose_name='Дата заявки')
order_adress = ChainedForeignKey(
'MarketAdress',
chained_field = "order_customer",
chained_model_field= "customermarkeradress",
show_all = False,
auto_choose = True,
sort = True,
verbose_name= 'Адреса точки')
order_number = models.CharField(max_length=10, verbose_name='Номер заявки')
# oder_brand = models.ForeignKey('CustomerBrand', on_delete=models.CASCADE, verbose_name="Назва вивіски")
oder_brand = ChainedForeignKey(
'CustomerBrand',
chained_field = "order_customer",
chained_model_field= "customer",
show_all = False,
auto_choose = True,
sort = True,
verbose_name= 'Вивіска')
class Meta:
verbose_name = 'Заявка'
verbose_name_plural = 'Заявки'
def __str__(self):
"""
String for representing the Model object.
"""
return str(self.oder_brand)
admin.py
#admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['customer_name', 'customer_inn', 'сontract', 'orders_lists', 'orders_add']
inlines = [OrderInline, EnvironmentActInstanceInline]
def сontract(self, obj):
link_buttom = reverse('downloadWordcontarct', args=[obj.pk])
return mark_safe(f'<a class="button" label="Догорів" href="{link_buttom}">Сформувати</a>')
сontract.short_description = "Договір"
def orders_lists(self, obj):
argsus=obj.pk
link_buttom = reverse("admin:catalog_order_changelist") + "?" + "order_customer__id=" + str(argsus)
#return format_html('{} order', link_buttom)
return mark_safe(f'<a class="button" label="Заявки" href="{link_buttom}">Перейти до заявки</a>')
orders_lists.short_description = "Заявки"
def orders_add(self, obj):
argss=obj.pk
link_buttom = reverse ("admin:catalog_order_add") + "?" + "order_customer=" + str(argss)
return mark_safe(f'<a class="button" label="Заявки" href="{link_buttom}">Створити</a>')
orders_add.short_description = "Додати заявку"
#admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
list_display = ['order_customer', 'order_date', 'order_number', 'order_adress', 'oder_brand', 'butt_ord']
def butt_ord(self, obj):
link_buttom = reverse('downloadWordorder', args=[obj.pk])
return mark_safe(f'<a class="button" label="Заявка" href="{link_buttom}">Заявку</a>')
butt_ord.short_description = "Сформувати"
enter image description here
enter image description here

Related

django - How to create a form inside a detail view

I am creating an online debate app using Django. I have used a class-based list view to create different topics using pk and once I click on the topic it takes me to its details page and once I go to the detail page I need two text-boxes to enter my for point and against point and after entering the point I need to display the point below the text-box. I have created a list of topics but I'm unable to do the text-box to that particular page.
This is my models.py
class DebateModel(models.Model):
title = RichTextUploadingField(blank=True,null= True)
body = models.TextField(max_length = 5000 , null=True,blank=True)
date_published = models.DateTimeField(auto_now_add=True)
date_update = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class ForModel(models.Model):
DebateModel = models.ForeignKey(DebateModel,related_name="for_point",on_delete=models.CASCADE)
body = models.TextField(max_length = 5000)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s %s' % (self.DebateModel.title, self.body)
class AgainstModel(models.Model):
DebateModel = models.ForeignKey(DebateModel,related_name="against_point",on_delete=models.CASCADE)
body = models.TextField(max_length = 5000)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s %s' % (self.DebateModel.title, self.body)
this is my forms.py
class EditFor(forms.ModelForm):
class Meta:
model = ForModel
fields = ('body',)
widgets = {
'body': forms.Textarea(attrs={'class':'form-control'}),
}
this is my views.py
class HomeView(ListView):
model = DebateModel
template_name = "debate/home.html"
class ArticleDetailView(DetailView):
model = DebateModel
template_name = "debate/content.html"
context_object_name = 'debate'
class AddForView(CreateView):
model = ForModel
template_name="debate/content.html"
form_class = EditFor
def form_valid(self,form):
form.instance.DebateModel_id = self.kwargs['pk']
return super().form_valid(form)
success_url = reverse_lazy('debate/home.html')
this is my urls.py
path('',HomeView.as_view(),name = "home"),
path('article/<int:pk>',ArticleDetailView.as_view(),name = "debate-detail"),
path('article/<int:pk>/forpoint',AddForView.as_view(),name="add_For"),
This is my content.html
<button onclick="myFunction()">for</button>
<button onclick="myFunction()">against</button>
<form method="post" action="Add_For/">
{%csrf_token%}
</form>
<script>
function myFunction() {
var x = document.createElement("TEXTAREA");
var t = document.createTextNode("enter your for point");
var y = document.createElement("INPUT");
y.setAttribute("type", "submit");
document.body.appendChild(y);
x.appendChild(t);
document.body.appendChild(x);
}
</script>

Django / Customized ModelChoiceField: how label_from_instance works?

I use ModelChoiceField with initial value just for display (readonly field).
But value displayed is model id and I want to display customized value that will be a concatenation of 3 fields. I've override ____str____ method but it is not applyed.
I try to make customize ModelChoiceFiedl to define label_from_instance that seems to be the way to do what I want but it is not applyed...
models.py
class Utilisateur(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
uti_ide = models.AutoField(primary_key = True)
# pro_ide = models.ForeignKey(Projet, on_delete = models.CASCADE) # related project
projets = models.ManyToManyField(Projet, through='UtilisateurProjet')
uti_nom = models.CharField("Nom", max_length=20)
uti_pre = models.CharField("Prénom", max_length=20)
uti_mai = models.CharField("Email", max_length=40)
uti_sit = models.CharField("Equipe", max_length=20, null=True, blank=True)
uti_pro = models.CharField("Fonction/profil", max_length=200, null=True, blank=True)
uti_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
uti_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)
log = HistoricalRecords()
#classmethod
def options_list(cls,pro_ide):
# projet = Projet.objects.get(pro_ide=pro_ide)
# utilisateurs = Utilisateur.objects.filter(pro_ide=projet.pro_ide)
utilisateurs = Utilisateur.objects.filter(projets__pro_ide=pro_ide)
the_opts_list = [(utilisateur.uti_ide, utilisateur.uti_nom+', '+utilisateur.uti_pre) for utilisateur in utilisateurs]
the_opts_list.insert(0, (None, ''))
return the_opts_list
class Meta:
db_table = 'tbl_uti'
verbose_name_plural = 'Utilisateurs'
ordering = ['uti_ide']
def __str__(self):
return f"{self.uti_nom}, {self.uti_pre} ({self.uti_mai})"
forms.py
class UtilisateurModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
print('label')
return obj.uti_nom+', '+obj.uti_pre+' ('+obj.uti_mai+')'
class UtilisateurProjetUpdateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(UtilisateurProjetUpdateForm, self).__init__(*args, **kwargs)
# print('kwargs',self.request)
# print('projet',self.request['projet'])
# print('utilisateur',self.request['utilisateur'])
PROJETS = Projet.objects.all()
UTILISATEURS = Utilisateur.objects.all()
self.fields["pro_ide"] = forms.ModelChoiceField(queryset = PROJETS, label = "Nom projet", widget = forms.HiddenInput(), initial = Projet.objects.get(pro_ide=self.request['projet']))
self.fields["uti_ide"] = UtilisateurModelChoiceField(queryset = UTILISATEURS, label = "Nom, prénom de l'utilisateur", widget = forms.TextInput(attrs={'readonly':'readonly'}), initial = Utilisateur.objects.get(uti_ide=self.request['utilisateur']),) #,to_field_name="uti_nom"
class Meta:
model = UtilisateurProjet
fields = ('pro_ide','uti_ide',)
in forms.py under that last class Meta: you need to add:
field_classes = {
'pro_ide': UtilisateurModelChoiceField,
'uti_ide': UtilisateurModelChoiceField,
}

how to change models field value from views in django

I want to set the value of is_delete field True when i click delete button from list page.
This is my views.py file
def delete_faculty(request, faculty_id):
faculty = Faculty.objects.get(id=faculty_id)
faculty.is_delete = True
return redirect('faculty-list')
This is models.py
class Faculty(models.Model):
name = models.CharField(max_length=255, unique=True)
established = models.DateField()
about = models.TextField()
status_choice = (
('active', 'Active'),
('disabled', 'Disabled'),
('paused', 'Paused')
)
status = models.CharField(choices=status_choice, max_length=15)
is_delete = models.BooleanField(default=False)
def __str__(self):
return self.name
This code can not set the value of True in is_delete field . How can i solve this?
# You just need to save the data
def delete_faculty(request, faculty_id):
faculty = Faculty.objects.get(id=faculty_id)
faculty.is_delete = True
faculty.save()
return redirect('faculty-list')

How can I customize url output?

I'm building a site using Django for equipment management. I am currently using this tutorial to help me get started.
I would like for the url displaying in the url bar in a browser to show something such as:
127.0.0.1:8000/catalog/model/model_number
But at the moment it just shows a single integer like 1, 2, 3, etc. when I click on each individual model.
Here is my urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='books'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
path('models/', views.ModelListView.as_view(), name='models'),
path('model/<int:pk>', views.ModelDetailView.as_view(), name='model-detail'),
]
I know that path('model/<int:pk>'... is the part that should be changed. I've tried path('model/model.model_number>'... but this outputs the below error:
Reverse for 'model-detail' with arguments '('2',)' not found. 1 pattern(s) tried: ['catalog\\/model\\/\\<model\\.model_number\\>$']
Here is my models.py:
from django.db import models
from django.urls import reverse #Used to generate URLs by reversing the URL patterns
import uuid
import datetime
# Create your models here.
class Genre(models.Model):
"""Model representing book genre"""
name = models.CharField(max_length = 200, help_text = 'Enter book genre')
def __str__(self):
"""String for represnting model object."""
return self.name
class Book(models.Model):
"""Model representing a book (but not a specific copy of a book)"""
title = models.CharField(max_length = 200)
author = models.ForeignKey('Author', on_delete = models.SET_NULL, null = True)
# Foreign Key used because book can only have one author, but authors can have multiple books
# Author as a string rather than object because it hasn't been declared yet in the file.
summary = models.TextField(max_length = 1000, help_text = 'Enter brief descp. of book') #TextField for longer descp.
isbn = models.CharField('ISBN', max_length = 13, help_text = '13 character ISBN number')
#ManyToManyField used because genre can contain many books. Books can cover many genres.
#Genre class has already been defined so we can specify the object above.
genre = models.ManyToManyField(Genre, help_text = 'Select genre for this book') #Genre capitalized, calling model up
def __str__(self):
"""String for representing the Model object."""
return self.title
def get_absolute_url(self):
"""returns the URL to access a detail record for this book."""
return reverse('book-detail', args=[str(self.id)])
class BookInstance(models.Model):
"""Model representing a specific copy of a book"""
id = models.UUIDField(primary_key = True, default = uuid.uuid4, help_text = 'Unique ID for this book across whole library')
book = models.ForeignKey('Book', on_delete=models.SET_NULL, null = True)
imprint = models.CharField(max_length = 200)
due_back = models.DateField(null = True, blank = True) #could do date scanned (date.now())
LOAN_STATUS = ( #could be ownership! Or make more of these for location
('m', 'Maintenance'), #being worked on, cleaned after field
('o', 'On loan'), #in the field
('a', 'Available'), #ready to go
('r', 'Reserved'), #in the field, could add one for 'being tested'
)
status = models.CharField(
max_length = 1,
choices = LOAN_STATUS,
blank = True,
default = 'm',
help_text = 'Book availability',
)
class Meta:
ordering = ['due_back']
def __str__(self):
"""String for representing the Model object."""
return f'{self.id} ({self.book.title})' #Will pop up on admin page as this
class Author(models.Model):
"""Model representing an author"""
first_name = models.CharField(max_length = 100)
last_name = models.CharField(max_length = 100)
date_of_birth = models.DateField(null = True, blank = True)
date_of_death = models.DateField('Died', null = True, blank = True)
class Meta:
ordering = ['last_name', 'first_name']
def get_absolute_url(self):
"""Returns the url to access a particular author instance."""
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
"""String for representing the Model object."""
return f'{self.last_name}, {self.first_name}' #Will pop up on admin page as this
class Location(models.Model):
town_city_base = models.CharField('Town/City/Base', max_length = 25, help_text="If location is classified enter CLASSIFIED in CAPS")
state = models.CharField(max_length = 25)
country = models.CharField(max_length = 25)
class Meta:
ordering = ['town_city_base', 'state', 'country']
def get_absolute_url(self):
#Returns the url to access a particular location instance
return reverse('location-detail', args=[str(self.id)])
def __str__(self):
#String for representing the Model object
return f'{self.town_city_base}, {self.state}, {self.country}'
class Category(models.Model):
category = models.CharField('Equipment Type', max_length = 50, help_text = "Enter general category of equipment")
class Meta:
verbose_name_plural = "categories" #default would have shown as "Categorys" on admin page
def __str__(self):
return self.category
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length = 50, help_text = "Original manufacturer or supplier")
def __str__(self):
return self.manufacturer
class Model(models.Model):
model_number = models.CharField('Model Number', max_length = 50)
manufacturer = models.ForeignKey('Manufacturer', on_delete = models.SET_NULL, null = True)
category = models.ForeignKey('Category', on_delete = models.SET_NULL, null = True)
description = models.TextField(max_length = 1000, help_text = "Enter brief description of product", null = True) #TextField for longer descriptions
def __str__(self):
return f'{self.model_number}..........{self.description}'
def get_absolute_url(self):
#Returns the url to access a particular location instance
return reverse('model-detail', args=[str(self.id)])
class Ownership(models.Model):
ownership = models.CharField('Ownership', max_length = 50)
class Meta:
verbose_name_plural = "Owners"
def __str__(self):
return self.ownership
def get_absolute_url(self):
return reverse('ownership-detail', args=[str(self.id)])
class ModelInstance(models.Model):
asset = models.CharField('Asset Number', max_length = 50, help_text = "Enter Weston or Government I.D. Tag Number")
model = models.ForeignKey('Model', on_delete = models.SET_NULL, null = True, help_text = "Leave blank if no model number exists")
serial = models.CharField('Serial Number', max_length = 50, null = True, blank = True, help_text = "Leave blank if no serial number exists")
location = models.ForeignKey('Location', on_delete = models.SET_NULL, null = True, help_text = "Enter current location or location after manufacturing")
ownership = models.ForeignKey('Ownership', on_delete = models.SET_NULL, null = True, help_text = "Enter current owner of equipment")
STATUS = (
('M', 'Maintenance'), #being worked on, not available
('D', 'Deployed'), #in the field
('A', 'Available'), #ready to go
('R', 'Reserved'), #Being used for classified/other project
('K', 'Broken'), #Broken
)
status = models.CharField(
max_length = 1,
choices = STATUS,
blank = True,
default = 'A',
help_text = 'Equipment Availability',
)
note = models.TextField('Notes', max_length = 1000, null = True, blank = True)
date_added = models.DateField("Date Added", default=datetime.date.today)
def __str__(self):
return f'Asset Number: {self.asset}..........Serial Number: {self.serial}..........Location: {self.location}..........Ownership: {self.ownership}'
You don't use the url to access the model's fields so
model.model_number>
is not going to help you.
If you want this url:
/catalog/model/model_number
You have to code it literally as it is:
path('catalog/model/model_number/<int:pk>/', views.ModelDetailView.as_view(), name='model-detail'),
]
It is good practice to add a backlash to the end.
Bear in mind that if the app name is catalog it is not necessary to add it to the path.
Now the pk of course is necessary to be passed to the view to retrieve the object you want, so you'll have this url in the browser:
127.0.0.1:8000/catalog/model/model_number/1/

django-select2 not working with inlines in django-admin

Here are my models and admin classes:
---------------------Models-----------------------
from django.contrib.auth.models import User
class PurchaseOrder(models.Model):
buyer = models.ForeignKey(User)
is_debit = models.BooleanField(default = False)
delivery_address = models.ForeignKey('useraccounts.Address')
organisation = models.ForeignKey('useraccounts.AdminOrganisations')
date_time = models.DateTimeField(auto_now_add=True)
total_discount = models.IntegerField()
tds = models.IntegerField()
mode_of_payment = models.ForeignKey(ModeOfPayment)
is_active = models.BooleanField(default = True)
class Meta:
verbose_name_plural = "Purchase Orders"
def __unicode__(self):
return '%s' % (self.id)
----------------------------------Admin----------------------------------------
"""
This class is used to add, edit or delete the details of item purchased
"""
class PurchasedItemInline(admin.StackedInline):
form = ItemSelectForm
model = PurchasedItem
fields = ['parent_category', 'sub_category', 'item', 'qty', ]
extra = 10
class BuyerChoices(AutoModelSelect2Field):
queryset = User.objects.all()
search_fields = ['username__icontains', ]
class BuyerForm(ModelForm):
user_verbose_name = 'Buyer'
buyer = BuyerChoices(
label='Buyer',
widget=AutoHeavySelect2Widget(
select2_options={
'width': '220px',
'placeholder': 'Lookup %s ...' % user_verbose_name
}
)
)
class Meta:
model = PurchaseOrder
fields = '__all__'
"""
This class is used to add, edit or delete the details of items
purchased but buyer has not confirmed the items purchased, this class
inherits the fields of PurchaseOrder derscribing the delivery address of
buyer , is_debit , total discount , tds and mode of payment
"""
class PurchaseOrderAdmin(admin.ModelAdmin):
form = BuyerForm
#list_display = ['id','buyer','delivery_address','date_time','is_active']
inlines = [PurchasedItemInline]
# model = PurchaseOrder
#actions = [mark_active, mark_inactive]
#list_filter = ['date_time']
#search_fields = ['id']
list_per_page = 20
def response_add(self, request, obj, post_url_continue=None):
request.session['old_post'] = request.POST
request.session['purchase_order_id'] = obj.id
return HttpResponseRedirect('/suspense/add_distance/')
I am trying to implement django-select2, but when I use inlines in
PurchaseOrderAdmin it doesn't show the field where I have implemented
django-select2:
But when I remove inlines, it works fine:
Edit
Here is the ItemSelectForm
class ItemSelectForm(forms.ModelForm):
class Media:
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
'js/ajax.js',
)
try:
parent_category = forms.ModelChoiceField(queryset=Category.objects.\
filter(parent__parent__isnull=True).filter(parent__isnull=False))
sub_category_id = Category.objects.values_list('id',flat=True)
sub_category_name = Category.objects.values_list('name',flat=True)
sub_category_choices = [('', '--------')] + [(id, name) for id, name in
itertools.izip(sub_category_id, sub_category_name)]
sub_category = forms.ChoiceField(sub_category_choices)
except:
pass
item = forms.ModelChoiceField(queryset = Product.objects.all())
def __init__(self, *args, **kwargs):
super(ItemSelectForm, self).__init__(*args, **kwargs)
self.fields['parent_category'].widget.attrs={'class': 'parent_category'}
self.fields['sub_category'].widget.attrs={'class': 'sub_category'}
self.fields['item'].widget.attrs={'class': 'item'}
It worked for me by adding the following line in the static/suit/js/suit.js
Add:
(function ($) {
Suit.after_inline.register('init_select2', function(inline_prefix, row){
$(row).find('select').select2();
});