Default django-admin list filter - django-admin

My question is just an extension of this thread [Question]http://stackoverflow.com/questions/851636/default-filter-in-django-admin .
from myproject.myapp.mymodels import fieldC
class Poll(models.Model):
fieldA = models.CharField(max_length=80, choices=CHOICES.MyCHOICES)
fieldB = models.ForeignKey(fieldC)
admin.py
list_display = ('fieldB__fieldc1')
Now my list filter shows four criteria All, A ,B ,C .
What I want is if the superuser is logged in ,the filter should show all four criteria All,A,B,C and if the user is other than superuser filter should only show All, A, B.
How can i acheive this ?
Here is my actual piece of admin.py
def changelist_view(self, request, extra_context=None):
referer = request.META.get('HTTP_REFERER', '')
test = referer.split(request.META['PATH_INFO'])
if test[-1] and not test[-1].startswith('?'):
if not request.GET.has_key('patient__patient_type__exact'):
q = request.GET.copy()
q['patient__patient_type__exact'] = 'Real'
request.GET = q
request.META['QUERY_STRING'] = request.GET.urlencode()
if not request.user.is_superuser:
q['patient__patient_type__exact'] = 'Real'
return super(VisitAdmin, self).changelist_view(request, extra_context)
Thanks in advance

I think the new FilterSpec API in Django 1.4 gives you exactly what you need here. Check out the docs on list_filter. In 1.4 you can now make custom list filters that subclass django.contrib.admin.SimpleListFilter and give you the power to write custom lookup and queryset code, and since the request is passed in you can do a simple conditional with is_superuser.
if request.user.is_superuser:
# pass one set of lookups
else:
# pass a different set
read the example code in the docs carefully and I think it will all be clear.

Related

How to get Twitter mentions id using academictwitteR package?

I am trying to create several network analyses from Twitter. To get the data, I used the academictwitteR package and their get_all_tweets command.
get_all_tweets(
users = c("LegaSalvini"),
start_tweets = "2007-01-01T00:00:00Z",
end_tweets = "2022-07-01T00:00:00Z",
file = "tweets_lega",
data_path = "tweetslega/",
bind_tweets = FALSE
)
## Binding JSON files into data.frame objects
tweets_bind_lega <- bind_tweets(data_path = "tweetslega/")
##Tyding
tweets_bind_lega_tidy <- bind_tweets(data_path = "tweetslega/", output_format = "tidy")
With this, I can easily access the ids for the creation of a retweet and reply network. However, the tidy format does not provide a tidy column for the mentions, instead it deletes them.
However, they are in my untidy df tweets_bind_lega , but stored as a list tweets_bind_afd$entities$mentions. Now I would like to somehow unnest this list and create a tidy df with a column that has contains the mentioned Twitter user ids.
Has anyone created a mention network with academictwitteR before and can help me out?
Thanks!

Odoo dynamic many2one domain

I want to apply dynamic filter to a many2one field (F1) based on another field (F2). I've done that using #api.change decorator, and it works but not as expected.
When i create a new entity, i change the value of F2, then go to F1, i find it filered, Oki no problem.
When i close the form, and then edit it again, and i go directly to the F1 field, i get again all available possibilities (not filtered), i need first to go to F2 and then choose the same value (already chosen previously) and then come back to F1.
Any idea ? (below the code: F1 = product_id which is inherited, and F2 = bom_id)
class ProductionLot(models.Model):
_inherit = "stock.production.lot"
company_id = fields.Many2one(default=lambda self: self.env['res.company']._company_default_get('account.invoice'))
bom_serial_number_line_ids = fields.One2many("mrp.bom.serialnumber.line", "parent_lot_id", "BoM Serial Numbers")
bom_id = fields.Many2one("mrp.bom", "BoM")
#api.onchange('product_id')
def update_bom_id_from_product_id(self):
for record in self:
if (record.product_id):
bom_complex_kit = record.product_id.env['mrp.bom']._bom_find(
product_tmpl=record.product_id.product_tmpl_id,
bom_type='complex_kit')
self.bom_id = bom_complex_kit
return {"domain": {"bom_id": [('product_tmpl_id.id', '=', record.product_id.product_tmpl_id.id),
('type', '=', 'complex_kit')]}}
As onchange filter will only be applied when the function is a trigger so it will only work when you change the on change value I guess what you need to do is this or combination of both onchange and default domain on field
def get_domain(self):
ids = self.env['stock.production.lot'].browse(self._context.get('active_ids'))
print("Here see all ids and use them accordingly",ids)
bom_id = fields.Many2one("mrp.bom", "BoM", domain = lambda self:self.get_domain())

Django admin custom search on custom column

Question:
How can I add the ability to search for items in my custom column Help Text?
FooAdmin View
Code:
Here is a simplified version of the code that I am working with:
models.py (yes this is how the models need to be set up)
class HelpText(models.Model):
help_text = models.CharField(max_length=1000)
def __str__(self):
return self.help_text
class Foo(models.Model):
job_name = models.CharField(max_length=200, blank=False, null=False)
env = models.CharField(max_length=200, blank=False, null=False)
def __str__(self):
return self.job_name
class FooHelpText(models.Model):
foo = models.OneToOneField(Foo, on_delete=models.DO_NOTHING)
help_text = models.ForeignKey(HelpText, on_delete=models.DO_NOTHING)
def __str__(self):
return str(self.help_text)
admin.py
class FooHelpTextInline(admin.TabularInline):
model = models.FooHelpText
#admin.register(models.Foo)
class FooAdmin(admin.ModelAdmin):
search_fields = ['env', 'job_name',]
list_display = ['pk', 'job_name', 'env', '_get_help_text', ]
inlines = [FooHelpTextInline]
def _get_help_text(self, obj):
return obj.foohelptext.help_text
Current behavior:
The current code above allows me to see the associated help_text in a column on FooAdmin. However, I am not able to search by anything in that column.
Not the answer I am looking for:
I know if it was the other way around where the help_text was a ForeignKey on Foo I could do something like foo__help_text, but that is not how my models are set up (and can not change).
Desired behavior:
Use the search box to search for help text (not just env and job_name).
Possible Solution (that I need help with):
I suspect that get_search_results might be what I need, but I don't understand how to implement it for my use case.
UPDATE:
The closest I can get is searching for a number(aka a specific PK that I know exists) and getting that search result. But the query doesn't really make sense. And obviously that is not the desired functionality of a search.
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= models.Foo.objects.select_related(
'foohelptext').filter(fooshelptext=search_term_as_int)
return queryset, use_distinct
I just don't understand the Python |= (bitwise OR operator) and why it has to be an integer.
Much easier than I thought. No need for get_search_results.
Simply needed to add it as foohelptext__help_text__help_text as an other item in the search fields.

how to change "xxx object" in django admin result list

Please take a look at this picture:
I am trying to change "business object" text to it's instance name. I wonder if there is an easy way to do that without dealing with django's core code.
This is the model I'm using:
class Business(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
description = models.TextField(blank=True)
industry = models.ManyToManyField(Industry)
class Meta:
verbose_name = 'Business'
verbose_name_plural = 'Businesses'
def __unicode__(self):
return "%s: %s" % (self.id, self.name)
Call the method __str__ instead of __unicode__. See https://docs.djangoproject.com/en/dev/intro/tutorial02/#playing-with-the-api and look for the info box called "__str__ or __unicode__?".
I had the same problem here. As Brenda J. Butler indicated (the link), it looks like if you are using Python 3.x you should define str() instead of unicode.

How to internationalize a message in grails with a hashmap (key:value)

I need to translate a message key using a Hashmap using the Grails standard internationalization method.
I receive an Enum and a map with the binding, which are going to be replaced in the text.
The Enum indicates, which key is going to be recovered. The bindings have the values to replace on the translation.
messageSource.getMessage("mail.layout.subject.${templateName}",ARGS,"",locale)
The problem is that I need to pass the map to the args like an array, not like a map, but I don't know the order of the args.
My question is, if there are any ways to create a tranlation key like:
mail.layout.subject.ENUM1=Blablabl {name} bablablabl {age}
Instead of
mail.layout.subject.ENUM1=Blablabl {0} bablablabl {1}
Finally I did it with brute force. May be is not the best answer but I coudln't find any one better.
Basically I get the translation with te message resources and then I work with it finding my custom expresions.
def messageSource = grailsApplication.getMainContext().getBean('messageSource')
def subject = messageSource.getMessage("mail.layout.subject.NOTIFICATION",null,"",locale)
An example of subject resource
mail.layout.subject.NOTIFICATION=The user {friend.name} is friend of {user}
An example bindings:
def bindings = [friend:[name:"Jhon",surname:"Smith"],user:"David"]
With this senteces I replace my expresions with the value of the bindings
Pattern pattern = Pattern.compile("\\{[^}]+\\}")
def res = subject.replaceAll(pattern,{
def expresion = it[1..it.size()-2] // removes brackets
def fields = expresion.split("\\.");
def res = bindings
fields.each{
println(it)
res = res."${it}"
}
return res
})
After the proces the subject becomes like: "The user Jhon is friend of David"
The example use a HashMap of HashMaps, but it also works with object because grails/groovy handles the object like HashMaps and viceversa
This is much cleaner. :)
import groovy.text.SimpleTemplateEngine
def text = 'Dear "$firstname $lastname",So nice to meet you in ${city.name}.See you in ${month},${signed}'
def binding = ["firstname":"Sam", "lastname":"Pullara", "city":["name":"San Francisco", "id":"28"], "month":"December", "signed":"Groovy-Dev"]
def engine = new SimpleTemplateEngine()
template = engine.createTemplate(text).make(binding)

Resources