(All code is some kind of pseudocode, just for better reading
I have an Invoice model:
class Invoice(models.Model):
// many fields here
I need to attach some products (with price for unit, and quantity fields) to this invoice, so I made additional table:
class InvoiceProduct(models.Model):
product = models.ForeignKey
quantity = models.IntegerField
unit_price = models.DecimalField
invoice = models.ForeignKey(Invoice)
So, this is almost first question — «Could it be done better way?»
My second problem is, that in django admin I have manage these models by inlines:
Screenshot
But my customer wants otherwise. He wants one button (Add product) then pop-up windows appears, with fields:
product, quantity, unit price. He fills them, press OK. Then pop-up window closes and line with "product fields" appears in main form.
I suppose I need override admin form template? Or I need to write my own widget or smth like that?
Sorry for my English.
My suggestion for your customer's request
He wants one button (Add product) then pop-up windows appears, with fields: product, quantity, unit price. He fills them, press OK.
Do NOT use the django admin for this. Only use it for people who want to access the data almost directly. In my head I see it just one half step up from the database itself. This means it is not suitable for users rather than administrators.
Or I need to write my own widget or smth like that?
Yes
Related
I have a few forms that retrieve objects through a ForeignKey, e.g. Flight, Trip.
So, for example, when someone tries to create a new Trip, they can choose an Hotel from a dropdown.
My question is: how can we, on the Trip form, add an Hotel. Just like when using Django's own admin dashboard, where you get a plus sign, and you can add a new Hotel while creating a Trip.
Edit:
Hotel is a ForeignKey on the Trip model.
And I am using ModelForm.
The objective is that you can either choose an existing Hotel or create a new one while creating a Trip.
I think you are looking for forms.ModelChoiceField.
It is used this way:
hotel = forms.ModelChoiceField(
queryset=Hotel.objects.all() # or whatever queryset you want to use
# Rest of the configuration
)
If I'm not mistaken, it will create an Html Select tag having options with pk of each Hotel object as the value. To specify the inner text of each option, you have to define the following method for the Hotel class:
def __str__(self):
return self.name # or whatever needed
If you indeed were looking for this I have to discourage you from using it if you are building a production-grade website/app. A better (and obviously more elaborate) approach is to get the query set of Hotels, serialize them to JSON, create a card/row/widget for each hotel for the user to search and select. However, it is a quick and handy way of managing small projects.
I'm using th purchase app on OpenErp.
I know this field is declared on purchase.py and called on purchase_view.xml but strangely it doesn't appears when i'm trying to add a new product quotation or purchase, don't get me wrong, the app works, but i find it amusing that this field isn't showing at all.
This is the field code on purchase.py
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
And the call on purchase_view.xml
<field name="product_uom" groups="product.group_unidadmedida" on_change="onchange_product_unidadmedida(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)"/>
Both on the same class purchase_order_line btw
Any hint on this?
Would please check you have given rights of "group_unidadmedida" to your user?
You need to assign this group to your logged user to see Unit of Measure in Purchase order.
"Manage Multiple Units of Measure"
Go to the Settings --> Users --> Users. Open logged user record. Go to Access Rights tab and first tick the "Technical Features", save it, reload it. Again open the same user record from menu. Now you will see some more groups under "Technical Settings: separator. Tick the "Manage Multiple Units of Measure" , save it and reload it. Now again open Purchase order form and you will be able to see Product UOM inside it.
I'm a beginner in Python and Django.
I have installed django-oscar. Then I Configured it and started the server, it works.
Now, I don't understand how to add a product?
At the dashboard there is a button Create new product. But in order to add new product it asks to select product class and I can not find any product class in the given dropdown options.
Provide me a demo example of how to add product in django-oscar.
You need to be logged in as a superuser and go to the store/dashboard URL
DO NOT ADMINISTER THIS FROM THE NORMAL DJANGO ADMIN CONSOLE (even though that answer was accepted?)
Here is an example of what this looks like in the included sandbox app
You need to add a category, product type, and partner and only then can you begin adding real products
Check out this commit - it hasn't been merged to the Oscar's master yet, but should give you an idea on how you can create products programmatically, for instance when importing data.
https://github.com/ArtS/django-oscar/blob/3f9abaf8d5c179c385b90dfa463a35ff9f92f73c/docs/source/recipes/importing_a_catalogue.rst
There is a separate page to administer product types, complete with a "Create new product type" button.
Using django-admin is not a good solution, you may be able to add product types and products through it, but you'll be missing out on any dashboard hooks into the normal process.
A look at the source code shows that whilst you may be able to add a product without a type (the FK is nullable), you may then experience other problems down the line as oscar expects only child products to have a null product_class.
#: None for child products, they inherit their parent's product class
product_class = models.ForeignKey(
'catalogue.ProductClass', null=True, on_delete=models.PROTECT,
verbose_name=_('Product Type'), related_name="products",
help_text=_("Choose what type of product this is"))
Definitely best to try to work with the system rather than around.
You have to add atleast one product class /admin/catalogue/productclass/
This are my first steps with django so please take no offense if this seems trivial.
I have a very huge table mynames (~ 1 000 000 entrys) and I want to make this table editable in the django admin site. I hooked things up like described in the official django book: I have a model, and I registered it by admin.site.register(mymodel). I can see the "table" on my admin site and I can click on it to see the first page full of names. That is nice so far. As soon as I click on the "show next page button" at the bottom of the page, the query seams to take forever.
Where could the problem be?
Update:
I added an index to the relevant column and now it is fast. I thought by doing
name = models.CharField(max_length=100, db_index=True, unique=True)
in the model definition there would be an index for this column. But there was none. Only unique index. Is this the way it should be or do I miss something?
It would be easier to see what the problem is if you pasted your full model class. Is there a specified ordering on the table? If so, you need to create a corresponding index to make pagination on that field fast. Is the list_display attribute set on the ModelAdmin class for the model? By default, django should order the rows based on the primary key so you should not need an additional index. Also check if you have overridden the __unicode__ method for the model in a way that causes additional database lookups when showing the entity in django admins table?
I've got two django models (simplified):
class Product(models.Model):
name = models.TextField()
price = models.IntegerField()
class Invoice(models.Model):
company = models.TextField()
customer = models.TextField()
products = models.ManyToManyField(Product)
I would like to see the relevant products as a nice table (of product fields) in an Invoice page in admin and be able to link to the individual respective Product pages.
My first thought was using the admin's inline - but django used a select box widget per related Product. This isn't linked to the Product pages, and also as I have thousands of products, and each select box independently downloads all the product names, it quickly becomes unreasonably slow.
So I turned to using ModelAdmin.filter_horizontal as suggested here, which used a single instance of a different widget, where you have a list of all Products and another list of related Products and you can add\remove products in the later from the former. This solved the slowness, but it still doesn't show the relevant Product fields, and it ain't linkable.
So, what should I do? tweak views? override ModelForms? I Googled around and couldn't find any example of such code...
Maybe it is not what you expect but I would introduce InvoiceItem model which would link Invoice to Product. So you would have 2x 1:n instead of m:n relation. Then use inline custom form for InvoiceItem and raw_id_fields in that form for Product choice.
In InvoiceItem form then you could add readonly fields that would display values you need to display. You will have to provide data for these fields in Form's init reading them from InvoiceItem instance. Or you could also derive from raw_id_field widget and in render method of this widget append some additional data from the product model?
This is an old question, but I have related to it today.
You can find the answer here - https://blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/
The code:
class MyAdmin(admin.TabularInline):
fields = 'myfield',
def formfield_for_dbfield(self, db_field, **kwargs):
formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == 'myfield':
# dirty trick so queryset is evaluated and cached in .choices
formfield.choices = formfield.choices
return formfield
This can cut your waiting times from anything like 5 minutes to around 15 seconds.