Django - Get database alias from QuerySet - django

I want to set a dynamic upload_to in the ImageField fields using a method. Something like this:
def content_file_name(instance, filename):
return '/'.join(['content', instance.database_alias, filename])
class Content(models.Model):
name = models.CharField(max_length=200)
user = models.ForeignKey(User)
file = models.FileField(upload_to=content_file_name)
Update
I don't know if is this useful, but I'm using Django 1.7.1
I'm doing a test with the model above:
models.py
from django.db import models
def content_file_name(instance, filename):
print "INSTANCE(%s)" % instance._state.db
return "/".join(instance._state.db, filename)
class Cliente(models.Model):
class Meta:
verbose_name = "Cliente"
verbose_name_plural = "Clientes"
Nombre = models.CharField("Nombre", max_length=50)
Foto = models.ImageField(upload_to=content_file_name)
def __unicode__(self):
return "Hello World"
MY_FIELDS = ["Nombre", "Foto"]
I'm getting in terminal on form submit:
Terminal
INSTANCE(None)
[19/May/2015 21:19:55] "POST /default/clientes/new HTTP/1.1" 500 168242
Another option could be making an import and get the database alias, but I don't know where get this from yet.

instance._state.db should return the database alias.

In Django 2.2.14, you can access the database alias using instance.db
qryset_employee = Employees.objects.using('OrgChartDatabase')
print(qryset_employee.db) ## Prints 'OrgChartDatabase'

Related

My views.py is returning null from django admin object

I would really appreciate some help on this because I'm completely stuck. I've started up a simple django app (trying to make an instagram clone). However, when I try to display the post objects (which I created in the django admin page) nothing is displayed in index.html, so I tried printing out the objects in the views.py and it's returning to me an empty query set. I don't quite understand what I'm doing wrong and why I can't access the objects? When I print out the username I am able to get that, but then nothing for both post and stream objects. Please I'm so stuck any advice would be appreciated.
views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.template import loader
from django.http import HttpResponse
# Create your views here.
from post.models import post, stream
#login_required
# we are getting all of the string objects that are created for the user
def index(request):
user = request.user
print(user)
posts = stream.objects.filter(user=user)
print(posts)
group_ids = []
#then looping through and getting post id to a list
for posted in posts:
group_ids.append(posted.post_id)
print(group_ids)
#then filtering them so that you can display it in the index
#selecting a specific post by id
post_items = post.objects.filter(id__in=group_ids).all().order_by('-date')
template = loader.get_template('index.html')
context = {'post_items' : post_items}
return(HttpResponse(template.render(context, request)))
models.py
from django.db import models
from django.contrib.auth.models import User
import uuid
# Create your models here.
from django.db.models.signals import post_save
from django.utils.text import slugify
from django.urls import reverse
def user_directory_path(instance,filename):
# this file is going to be uploaded to the MEDIA_ROOT /user(id)/filename
return('user_{0}/{1}'.format(instance.user.id,filename))
class tag(models.Model):
title = models.CharField(max_length = 80, verbose_name = 'tag')
slug = models.SlugField(null = False, unique = True)
class Meta:
verbose_name = 'tag'
verbose_name_plural = 'tags'
# for when people click on the tags we can give them a url for that
# def get_absolute_url(self):
# return(reverse('tags', args = [self,slug]))
def __str__(self):
return(self.title)
def save(self,*args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
return(super().save(*args, **kwargs))
class post(models.Model):
# will create a long id for each post
id = models.UUIDField(primary_key=True, default = uuid.uuid4, editable = False)
image = models.ImageField(upload_to = user_directory_path, verbose_name= 'image', null = True)
caption = models.TextField(max_length = 2000, verbose_name = 'caption')
date = models.DateTimeField(auto_now_add = True)
tags = models.ManyToManyField(tag, related_name='tags')
user = models.ForeignKey(User, on_delete=models.CASCADE)
likes = models.IntegerField()
def get_absolute_url(self):
return reverse('postdetails', args=[str(self.id)])
# def __str__(self):
# return(self.user.username)
class follow(models.Model):
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower')
following = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following')
class stream(models.Model):
following = models.ForeignKey(User, on_delete=models.CASCADE, related_name='stream_following')
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(post, on_delete=models.CASCADE)
date = models.DateTimeField()
def add_post(sender, instance,*args, **kwargs):
# here we are filtering all the users that are following you
post = instance
user = post.user
followers = follow.objects.all().filter(following=user)
for follower in followers:
streams = stream(post=post, user=follower.follower, date = post.date, following = user)
streams.save()
post_save.connect(stream.add_post, sender=post)
output from print statements
user
<QuerySet []>
[]
I figured it out. It wasn't an issue with the code, but the way that I was creating posts in the admin panel. So because you can only view posts from users that you are following, the posts that I was creating weren't showing up. So I had to create another user, and follow that user, then have the new user post something. Then the post shows up in the page!

Django Admin escaping text

I recently upgraded Django from 1.3 to 1.8.18 and been having issues with links custom made to pre-fill forms in Django admin. For example, I have the following link:
/admin/miscellaneous/whatsnew/add/?title=...%20competition%20results%20uploaded&pub_date=21-04-2017&body=&link=
When executed the pre-filled data in the form looks like:
Where it should look like this:
When testing directly from the URL bar in Safari it changes to this after pressing enter:
https://flyball.org.au/admin/miscellaneous/whatsnew/add/?title=...%2520competition%2520results%2520uploaded&pub_date=21-04-2017&body=&link=
models.py
class WhatsNew(models.Model):
title = models.CharField(max_length=100,help_text='Title, MAX 100 characters.')
body = models.TextField()
pub_date = models.DateField()
message_expiry = models.DateField(default=datetime.date.today() + relativedelta(years=1))
link = models.URLField(blank=True, null=True)
class Meta:
ordering = ['-pub_date']
verbose_name_plural = "Whats New?"
def __unicode__(self):
return self.title
admin.py
import models
from django.contrib import admin
class WhatsNewAdmin(admin.ModelAdmin):
list_display = ('title','pub_date','message_expiry','link','body')
admin.site.register(models.WhatsNew, WhatsNewAdmin)
What can I do to resolve this?
So, I'm not sure how to do it on the ModelAdmin, but you can create custom setters on your model to handle this situation. Here's how I would go about escaping the URL encoded strings:
import urllib
class WhatsNew(models.Model):
# Field with custom setter
_title = models.CharField(max_length=100,
help_text='Title, MAX 100 characters.',
db_column='title')
body = models.TextField()
pub_date = models.DateField()
message_expiry = models.DateField(default=datetime.date.today() + relativedelta(years=1))
link = models.URLField(blank=True, null=True)
# Custom getter and setter
#property
def title(self):
return self._title
#title.setter
def title(self, value):
self._title = urllib.unquote(value)
class Meta:
ordering = ['-pub_date']
verbose_name_plural = "Whats New?"
def __unicode__(self):
return self._title
Use + instead of %20 for space and it works.
Your link should be something like:
/admin/miscellaneous/whatsnew/add/?title=...+competition+results+uploaded&pub_date=21-04-2017&body=&link=

Django-CMS - CMS section of admin disappears when I specify a model

I'm trying to duplicate the example in 2.4 in the Django-CMS docs (http://docs.django-cms.org/en/2.3.5/extending_cms/custom_plugins.html). However, whenever I specify the model in cms_plugins.py under class HelloPlugin, the entire CMS section in the admin disappears. Any idea what's causing this?
models.py
from django.db import models
class MyModel(models.Model):
title = models.CharField(max_length=50, null=True, blank=True)
def __unicode__(self):
return self.title
from cms.models.pluginmodel import CMSPlugin
class HelloPlugin(CMSPlugin):
ad = models.ForeignKey('core.MyModel', related_name='plugins')
def __unicode__(self):
return self.ad.title
cms_plugins.py
class HelloPlugin(CMSPluginBase):
model = MyModel
name = _("MyModel Plugin")
render_template = "myplugin.html"
def render(self, context, instance, placeholder):
context['instance'] = instance
return context
plugin_pool.register_plugin(HelloPlugin)
Small, but significant mistake. I was importing the model, and not the plugin.

Foriegnkey issue while submitting the form

This post extends the error while submitting data in the form django
model.py
from django.db import models
# Create your models here.
class Profile(models.Model):
name = models.CharField(max_length=50, primary_key=True)
assign = models.CharField(max_length=50)
doj = models.DateField()
class Meta:
db_table= 'profile'
def __unicode__(self):
return u'%s' % (self.name)
class working(models.Model):
w_name =models.ForeignKey(Profile, db_column='w_name')
monday = models.IntegerField(null=True, db_column='monday', blank=True)
tuesday = models.IntegerField(null=True, db_column='tuesday', blank=True)
wednesday = models.IntegerField(null=True, db_column='wednesday', blank=True)
class Meta:
db_table = 'working'
def __unicode__(self):
return u'%s ' % ( self.w_name)
view.py
# Create your views here.
from forms import *
from django import http
from django.shortcuts import render_to_response, get_object_or_404
def index(request):
obj=working()
obj.w_name='X'
obj.Monday=1
obj.Tuesday=2
obj.Wednesday =3
obj.save()
return http.HttpResponse('Added')
Here i want to insert the data directly into table ,if person click on http://127.0.0.1:8000/
But it throws below error any thoughts ??
Exception Type: ValueError at /
Exception Value: Cannot assign "u'x'": "working.w_name" must be a "Profile" instance.
I thought you were saying you wanted to inject values into a form?
In this case, it's clear (see it's better than comments), you need to pass in a Profile instance to your working object just as we did in the form clean method in your other post.
def index(request):
try:
profile = Profile.objects.get(pk='X')
except Profile.DoesNotExist:
assert False # or whatever you wish
obj=working()
obj.w_name= profile
obj.Monday=1
obj.Tuesday=2
obj.Wednesday =3
obj.save()
return http.HttpResponse('Added')

How to show database in django-admin using filters by default?

I need to filter database by default every time that I see it (when I save changes or when I open database first time).
Can anybody tell me how to do it?
This is possible with custom custom Managers:
Say you have a class called Book:
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
And you want the admin pages for book objects to only show books by Roald Dahl, then you can add a custom manager:
class DahlBookManager(models.Manager):
def get_query_set(self):
return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
objects = models.Manager()
dahl_objects = DahlBookManager()
Then you just need to specify that your ModelAdmin should use the dahl_objects manager, which is explained here.
Here is my models.py:
from django.db import models
class DahlBookManager(models.Manager):
def get_query_set(self):
return super(DahlBookManager, self).get_query_set().filter(processed=False)
class Book(models.Model):
book_name = models.CharField('book',max_length=1000,null=True, blank=True)
url = models.CharField(max_length=1000,null=True, blank=True)
processed = models.BooleanField('Done',)
def __str__(self):
return u'%s' % (self.book_name)
def url1(self):
return '%s' % (self._url, self.url)
site_url1.allow_tags = True
class Admin:
pass
class Meta:
db_table = 'books'
objects = models.Manager()
dahl_objects = DahlBookManager()
here is my admin.py:
from django.contrib import admin
from mybooks.booksdb.models import Book
from django import forms
admin.autodiscover()
class BookAdmin(admin.ModelAdmin):
def queryset(self,request):
qs=self.model.objects.get_query_set()
ordering = self.ordering or ()
if ordering:
qs=qs.order_by(*ordering)
return qs
....
No filter by default. Where is my miss?