Django InLineSetModel and many2many field choices filtering - django-admin

I have a many2many field in my model and I'm trying to render it in django admin using the inlineform. Everything is fine, but I can't customize the form as I want.
The model is simple there is a Supplier and a manytomany field named locations
Supplier(models.Model):
location = models.ManyToManyfield(Location, blank=True)
the inlineform
class LocationInLineForm(admin.TabularInLine):
model = Supplier.Location.through
The first thing I want to is to limit the choices. The constrains are two:
The location model has a boolean field 'active' and I need to filter based on that
The Supplier must be the Supplier selected in the django admin.
The admin user load the django admin, click on the supplier and the InLineForm must show his active location.
I thought that the following method is the right one to ovverride:
def formfield_for_manytomany(self, db_field, request, **kwargs):
but is not called by the InLineForm. The on called is:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
The example in the django docs are based on the request.user but what I need is the current supplier where I can get it? In the request? But where? request.GET is empty. Maybe I can get it from db_field, but I don't know how.
If I can get the supplier id, I can create a queryset and pass it using kwargs['queryset']. Am I right?

Related

Changing the ID of a new object in Rails

So I have a Customer model in my Rails app and whenever a new customer is created I am getting a number as input from the user and I want that number to become the id of the customer on my database instead of the default 1, 2, 3, and so on. Is it possible to do that? If so, how?
EDIT: Let me be a more clear about what I want: I have a Customer and A Brand model. A customer has_many brands and a brand belongs_to a customer. Whenever the user creates a new brand, I want to connect it to its customer using that number that the user entered for the customer. Right now, whenever the user creates a new brand, I ask him to enter the customer_id value to connect the brand to a customer, but that is the id number generated by Rails. How do I make that customer_id attribute refer to the specific number the user entered for a customer, instead of the customer id generated by Rails.
It's possible, but don't do that. Just allow Rails to manage the auto-generated ID itself, and add this number - whatever it is - as a separate attribute in your model and saved to a separate field in your database.
As smathy mentioned, you can do the following:
1.First, generate a migration that add your custom attribute
rails g migration AddCustomerIdToCustomers customer_id:integer
2.When user enter the id, you would want to do something like this:
#customer.customer_id=params[:customer_id]
#customer.save
3.Then you can retrieve the custom object as
#customer = Customer.find_by_customer_id(customer_id)
where customer_id is the id you want.
As the above answer suggests, it is better let Rails handle the id attribute, because it is used extensively in Rails to handle database relationships ActiveRecord queries, etc. You do not want the extra headache of modifying it yourself.

Rails 4 Devise and STI

I read the two posts here and here, but still have trouble figuring out how everything is tied together. Basically I have 2 types of users, Trainers and Clients. They share some common attributes (email, phone, first name, last name, etc), but they will also have some custom attributes.
Assuming STI is the way to go, I would have 3 models:
User (devise)
Trainer (inherits from User)
Client (inherits from User)
When the user signs up, they should be able to use the same form and just select from a drop down if they're a trainer or client. Once the form is submitted how do I go about specifying the type of user that has just been created? Do I need logic in the controller to check the user type, and then run Trainer.create() or Client.create()?

How to code this in Rails?

I have three models and their corresponding tables and controllers:
Request
DirectPatch
UTPFiberPatch
The user creates a new request and defines the type of request: Direct or UTP/Fiber
Once the user hits save, the Request will be saved and the user will be redirected to an edit screen to create all the patch entries corresponding to that request.
Each patch entry will be saved as a single row in either the Direct or UTP table depending on the type of request selected. A column called request_id will act as the foreign key.
The view and form will be different for both Direct and UTP/Fiber.
The user can view all requests on a single homepage and click to edit. The user can then see all the patch rows for that request on a single page and click to edit existing or add new.
What would be the best way to set up the routing, controllers and
views for this?
How does the Request ID get passed when creating new patches and automatically saved?
I'm not sure exactly what the technical name is for the problem I'm having if there is one, but I'm happy to add more detail and answer questions if needed.
You could use a polymorphic association on the request model:
belongs_to :patch, :polymorphic => true
Add to your Request table two columns:
patch_id : integer
patch_type : string
When you create a request and the user selects the patch type, you assign this patch object to your request, which will populate the two new columns. From you request model you can then call
request.patch
Which will give you back the appropriate type of patch based on the details stored in the database (note - you can't do eager loading with polymorphic associations).
To do the views you can render a partial in the edit screen, based upon which type of patch it is.

Instance variable in rails - apart from views where can we use it and for how long is it available

I have created a instance variable in rails project, which gets its value from a url parameter like example.com/value. This variable is created in new action, now can it also be used in create action, of the same model.
The value is a id of another model altogether and both the models are associated, I need to create the instance variable in former model.
I need to know, for how long the instance variable is available, and can be use the instance variable of one model in another model.
Clarification with real example
Supposingly there are two models, one is User model and other is Referral model. The root is root :to => 'users#new. Now the user will coming here via example.com/value, where value is the id for Referral model. Now using this value I have to increment two fields: One is visits, which shows how many visits did that particular url bring. Other is signup, which will increment if there is a signup using that value.
I have passed this value via routes in users#new, which I use to increment the visits column of Referral model. Now if the users signup, the users#create would be executed, and I want to be able to use the value in the create action as well, to increment the signup column in Referral model.
As of now, I understand that the instance variable I created in new action to store the value cannot be used in create action. Now how can I achieve this.
In general instance variables only last as long as the user's HTTP request, so they can not be created in one action and used in another.
You could try storing the variable in the session, a hidden input field on the HTML form generated by the new action, or in the urls of links generated by the new action.
I don't know exactly what you are doing, but from the names of your two actions it sounds like there is probably an HTML form involved, so I think the best thing is to use a hidden input, something like this:
<input type="hidden" name="model_id" value="<%= #model_id %>" />
Instance variables only last for that call and in the class they are defined, with the exception of the views. If you have a controller with two methods where one method is your route and another is used internally, then it will be available to both, it is also available to your views.
e.g.
test_controller.rb
def index
something_else
p #variable #outputs "foo" in the terminal
end
def something_else
#variable = "foo"
end
However it would not be available between create and new as these would be called in different requests.

How to force a filter as landing page in the list view?

I'd like, each time a user visit a model list in Django admin, to land in a page with a filter applied insted of no one applied.
In particular, I'd like to determine the filter applied based on a user attribute.
How can I achieve this?
edit:
Misread your question, sorry!
To select a default filter for a user based on an user attribute, use the changelist_view
Override the ModelAdmin queryset method.
http://docs.djangoproject.com/en/1.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset
example given is:
class MyModelAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = super(MyModelAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
change the filtering based on your user attribute.

Resources