Object label in GAE Django - django

In my usual django code I use the unicode function to give each object a label...this appears in the admin interface as the oject label in the objects listed...
class apprd(models.Model):
usr = models.ReferenceProperty(User)
approved = models.BooleanProperty(default = True)
def __unicode__(self):
return ('approved one')
but now i have moved to GAE and this feature does not seem to be supported...
is there any work around or am I doin a mistake

This isn't possible in GAE, because the GAE admin console does not read - indeed, has no access to - your model definitions. It only has access to the stored data.

If you use http://code.google.com/p/app-engine-patch/, you can get the full Django admin interface running inside GAE.

Related

Django: Custom default Manager with user based queries for all views/interfaces (custom, admin, graphene, rest, ...)

In Django I'm trying to implement some kind of a "security middleware", which gives access to certain db information only, if the logged in user matches.
Up to now I found two approaches: middleware or custom function in manager (Both explained here Django custom managers - how do I return only objects created by the logged-in user?).
Example for cleanest solution: custom function
class UserContactManager(models.Manager):
def for_user(self, user):
return self.get_query_set().filter(creator=user)
class MyUser(models.Model):
# Managers
objects = UserContactManager()
# then use it like this in views
data = MyUser.objects.for_user(request.user)
However, this solution only works, if you have control over the code which invokes this custom function (here: for_user()).
But if you are using third parties apps like Django-REST, Graphene or AdminViews, they don't have the possibility to configure a specific query-func to use.
My goal:
Replace the default Manager
Add user-based filters to query_set
Use the model as normal in all app configurations
Idea (pseudo code!)
from django.x import current_user
class UserBasedManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(author=current_user.name)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
objects = UserBasedManager() # The default manager.
Now I could use the model Book as normal in all extensions.
I know this solution would have some drawbacks, which are okay for me:
Can be only used when user is available (e.g. no direct script support)
Handling no or anonymous user is missing (left it away to keep example short)
My use case
I have a project, which shall give access to data by different interfaces (admin pages, custom views, rest, graphql).
As I have so many interfaces, I don't want to implement the access-rights in the views. This would cost too much time and is hard to maintain and the risk for security problems in one specific view/interface is too high.
Let's say I'm storing commits of git repositories in a database.
And the user shall get access to all commits, which are part of repos the user has READ access.
The question is: How can I implement this as a generic, view/interface independent solution?
Install django-threadlocals package and call get_current_user function to get the current user
from threadlocals.threadlocals import get_current_user
class UserBasedManager(models.Manager):
def get_queryset(self):
current_user = get_current_user()
return super().get_queryset().filter(author=current_user.name)

Django REST Framework - Change ID Format

I am currently playing around with Django + Django REST Framework to build an API layer. A question I was curious about is if it's possible to change the id layout. Currently my model looks something like this:
class Thing(models.Model):
name = models.CharField(max_length=100)
class ThingContainer(models.Model):
name = models.CharField(max_length=100)
things = models.ManyToManyField(Thing)
This means that DRF (using ModelViewSet and ModelSerializer) automatically generates API endpoints like /things/1 or /thing_containers/2.
I was wondering if there is a neat trick to change the format of the outward-facing ID. So instead of /things/1 it would be /things/YXBwOi8vdGhpbmcvMQ== which is the base64 encoding of app://things/1.
I am aware that I could change the key of the model itself into a CharField and enforce that format on the DB level. However that comes with its own set of performance issues and other caveats.
You should override method retrieve in viewset. And fix url in urlpatterns

pycharm is not showing autocomplete for my own modules

I am using pycharm for a django project. I made an app named 'music' and there I created a model named 'Album'.
Inside Views I am using a for loop to get to the details stored in the database like this
all_albums = Album.objects.all()
for album in all_albums:
album.artist
however when I type album. I don't get autocomplete suggestions for artist or anything else that I have defined in that class.
How to make pycharm include my own modules in the autocomplete?
One way, using docstrings:
for each in qs:
payment = each
"""#type : Payment """
print payment.deadline
Another way, using assert:
for each in qs:
assert isinstance(each, Payment)
print each.deadline
You can Google 'pycharm type hinting' or similar to find out more.

Django form DateField initial value not updating in Apache

I have a Django form that includes a DateInput like this:
Fecha = forms.DateField(widget=DateInput(format = '%Y-%m-%d'),initial=(date.today() - timedelta(1)))
The idea is that every time you access the template that contains the form, it automatically shows the day-1 date.In my development environment this works as expected.However, I've noticed something strange in my production environment. The DateField initial value doesn't change unless I restart my Apache Server. For example, if I restart Apache right now my form will show 2015-02-26 as the initial date and will stay like that until I restart Apache again. I'm not sure if this is Django related or it has more to do with Apache configuration. Any suggestions or workarounds? Thanks in advance!!!!
Regards,
Alejandro
Shouldn't it be like this:
def get_yesterday():
return datetime.today() - timedelta(days=1)
mydatefield = forms.DateField(widget=DateInput(format = '%Y-%m-%d'),initial=get_yesterday)
Your code would evaluate the date.today() function at server initialization and not at form initialization.
This is neither a django issue nor an Apache configuration problem, but rather a result of how and when Python evaluates code. Class attributes are evaluated as soon as the module containing a class is imported/brought into memory. So your form class's Fecha attribute is evaluated only initially when your app starts, and not evaluated again until your app is restarted.
To handle this, simply provide initial date values when your view instantiates your form object instead of in your form class definition. This will work because your view function executes every time you refresh the page:
import MyForm
def my_view(request):
my_form_instance = MyForm(initial={'Fecha': date.today() - timedelta(1)})
...

Multiple images per Model

I'm writing a simple real-estate listing app in Django. Each property needs to have a variable number of images. Images need to have an editable order. And I need to make the admin user-proof.
So that said, what are my options?
Is there a ImageList field that I don't know about?
Is there an app like django.contrib.comments that does the job for me?
If I have to write it myself, how would I go about making the admin-side decent? I'm imagining something a lot slicker than what ImageField provides, with some drag'n'drop for re-ordering. But I'm a complete clutz at writing admin pages =(
Variable lists, also known as a many-to-one relationship, are usually handled by making a separate model for the many and, in that model, using a ForeignKey to the "one".
There isn't an app like this in django.contrib, but there are several external projects you can use, e.g. django-photologue which even has some support for viewing the images in the admin.
The admin site can't be made "user proof", it should only be used by trusted users. Given this, the way to make your admin site decent would be to define a ModelAdmin for your property and then inline the photos (inline documentation).
So, to give you some quick drafts, everything would look something like this:
# models.py
class Property(models.Model):
address = models.TextField()
...
class PropertyImage(models.Model):
property = models.ForeignKey(Property, related_name='images')
image = models.ImageField()
and:
# admin.py
class PropertyImageInline(admin.TabularInline):
model = PropertyImage
extra = 3
class PropertyAdmin(admin.ModelAdmin):
inlines = [ PropertyImageInline, ]
admin.site.register(Property, PropertyAdmin)
The reason for using the related_name argument on the ForeignKey is so your queries will be more readable, e.g. in this case you can do something like this in your view:
property = Property.objects.get(pk=1)
image_list = property.images.all()
EDIT: forgot to mention, you can then implement drag-and-drop ordering in the admin using Simon Willison's snippet Orderable inlines using drag and drop with jQuery UI
Write an Image model that has a ForeignKey to your Property model. Quite probably, you'll have some other fields that belong to the image and not to the Property.
I'm currently making the same thing and I faced the same issue.
After I researched for a while, I decided to use django-imaging. It has a nice Ajax feature, images can be uploaded on the same page as the model Insert page, and can be editable. However, it is lacking support for non-JPEG extension.
There is a package named django-galleryfield. I think it will meet your demand.