Using django-filebrowser and the FileBrowserField I am attempting to assign the directory parameter based off a key in the model itself. So using a blog example, if I were saving photos for different posts, the photos would be in directories named after the blog id. So if the MEDIA_ROOT was/some/path/to/media/filebrowser_files/ I wish to dynamically assign the directory paramter to be MEDIA_ROOT+str(model_pk)
At this point I have attempted to do something resembling the following, but do not understand how to obtain the id of the current object. (DoesNotExist exception with "No exception supplied") I know the error exists within the attempt to use self.page, but I do not know how to do this correctly. Could someone provide some insight as to where my logic is flawed and what I can do to fix it? Thanks much.
class PageImage(models.Model):
page = models.ForeignKey(Page)
page_photo = FileBrowseField("Image", max_length=200, blank=True, null=True)
def __init__(self, *args, **kwargs):
super(PageImage, self).__init__(*args, **kwargs)
path = settings.MEDIA_ROOT+'pages/unfiled/'
if self.page:
path = settings.MEDIA_ROOT+'pages/'+str(self.page)+'/'
if not os.path.exists(path):
os.makedirs(path)
self._meta.get_field_by_name("page_photo")[0].directory = path
I realize I didn't look closer at your code. self.page will not work because you're initializing the Model instance and self.page has not been set to a page in the database. You should try instead:
class PageImage(models.Model):
page = models.ForeignKey(Page)
page_photo = FileBrowseField("Image", max_length=200, blank=True, null=True)
def save(self, *args, **kwargs):
path = settings.MEDIA_ROOT+'pages/unfiled/'
if self.page:
path = settings.MEDIA_ROOT+'pages/'+str(self.page)+'/'
if not os.path.exists(path):
os.makedirs(path)
self._meta.get_field_by_name("page_photo")[0].directory = path
super(PageImage, self).save(*args, **kwargs)
doing what you want only after you've assigned a Page to the field in PageImage.
Related
I want to creato objects through admin-pannel Django, I enter a value for a parameter and I want a qr code to be generated based on this value, my code:
class People(models.Model):
name = models.CharField(max_length=500, unique=True)
qr_code = models.ImageField(upload_to="img/qr_codes/", verbose_name="QR-code", null = True)
def save(self, *args, **kwargs):
qr = qrcode.QRCode(version=2, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=1)
qr.add_data(self.name)
qr.make(fit=True)
qr.make_image().save(f'img/qr_codes/{self.name}.png')
self.qr_code = self.name+'.png'
super().save(*args, **kwargs)
This code return error
[Errno 2] No such file or directory: 'img/qr_codes/somename.png'
Im trying to use signal #receive but it isn't help for me
Make sure that your created the mentioned directories (img/qr_codes/). the method only creates file. It cannot create a directory.
Note: I think you missed a closing bracket ) after your f-string. Is that the same in your code?
I would like to build a hierarchy tree of content with no depth limits.
models.py:
class Element(models.Model):
name = models.CharField(verbose_name="Nombre", max_length=250)
parent = models.ForeignKey("self", on_delete=models.CASCADE)
slug = models.TextField(verbose_name="Slug", blank=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Element, self).save(*args, **kwargs)
.../element_n-1/element_n/element_n+1/...
How do I have to write the path in urls.py to get this functionality?
You can use path: type converter for your path() definition:
urlconf.py:
path('prefix/<path:path>', my_view),
More info: https://docs.djangoproject.com/en/3.1/topics/http/urls/#path-converters
views.py:
def my_view(request, path):
elements_list = path.split('/')
...
But as it was said in the previous answer, there's a limit for URL length so your path cannot include arbitrary number of elements.
Such URL is not possible to create in any web framework, because URLs have length limits (2000 characters long), so no web framework will allow a URL to accept growing dynamically based on a Model Hierarchy inside of it.
You need to think of another way to let your app deliver such functionality, in a different way other than URLs.
my problem is that I can not establish a reverse match, most likely doing something wrong with my url definition (?). Ultimately what I am trying to do is the following:
User selects 2 location points which the 'new_pointview' view, saves into a DB. I also define a unique slug which contains location information and save it to the DB via the save() within the model. Then the user should be redirected to a url (pointview view) which uses the slug I created in the previous step i.e /pointview/slug. Here is the code:
models.py
class Points(models.Model):
starting_point_longitude = models.FloatField(null=True)
starting_point_latitude = models.FloatField(null=True)
ending_point_longitude = models.FloatField(null=True)
ending_point_latitude = models.FloatField(null=True)
url = models.SlugField(max_length=250, null=True, unique=True, blank=False)
def save(self, *args, **kwargs):
self.url = 'start_lon-{0}-start_lat-{1}-end_lon-{2}-end_lat-' \
'{3}'.format(self.starting_point_longitude,
self.starting_point_latitude,
self.ending_point_longitude,
self.ending_point_latitude)
super(Points, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('pointview', kwargs={'url': self.url})
views.py
def pointview(request, url):
point = get_object_or_404(Points, url=url)
content = {'starting_point_longitude':
point.starting_point_longitude,
'starting_point_latitude':
point.starting_point_latitude,
'ending_point_longitude':
point.ending_point_longitude,
'ending_point_latitude':
point.ending_point_latitude}
return render(request, 'points.html', {'user_bundle': content})
def new_pointview(request):
Points.objects.create(
starting_point_longitude=request.POST['starting_point_longitude'],
starting_point_latitude=request.POST['starting_point_latitude'],
ending_point_longitude=request.POST['ending_point_longitude'],
ending_point_latitude=request.POST['ending_point_latitude'],
)
points_filtered = Points.objects.filter(
starting_point_longitude=request.POST[
'starting_point_longitude']).filter(
starting_point_latitude=request.POST[
'starting_point_latitude'])
unique_url = points_filtered.values()[0]['url']
return redirect('/pointview/{0}/'.format(unique_url))
urls.py
urlpatterns = [
path(r'^pointview/(?P<url>[-\w]+)/$', views.pointview, name='pointview'),
path('^new_pointview/', views.new_pointview, name='new_pointview'),
]
The error:
The current path, pointview/start_lon-738949.9146592747-start_lat--153698.8751025315-end_lon-759997.8063993475-end_lat--168467.65638300427/, didn't match any of URL patterns. Hope you can give me some feedback here..
For future reference, it was a regex problem, using the following non intuitive regex solved it:
url('^pointview/(?P<url>start_lon[--W]+start_lat[--W]+end_lon[--W]+end_lat[--W]+)/', views.pointview, name='pointview')
I would be very interesting though if someone can give a more elegant solution.
I am new to Django, so pardon me if my question is naive.
I am trying to achieve a use case of text mining application on uploaded files, I am trying to show a "Get Started" button in the landing / home page. On button click I am rendering a file upload option.
Now I am trying to treat this as a Scan Job, and wanting jobID to get created with the click of the button and the same jobID to be displayed further pages and this jobID to be used as primary key in other models.
Below is the model I created.
from django.db import models
class sfs_job_model(models.Model):
sfs_job_id = models.CharField(max_length=250,default="", editable=True)
sfs_job_start_date_time = models.DateTimeField(auto_now_add=True, null=False)
sfs_job_end_date_time = models.DateTimeField(auto_now_add=True,null=False)
sfs_job_status = models.CharField(max_length=250, editable=False,empty_value=None,null=True)
sfs_job_summary = models.CharField(max_length=1000)
def save(self, *args, **kwargs):
if self.job_id is None:
self.job_id = 'SFS-' + str(self.id)
return super(sfs_job_model, self).save(*args, **kwargs)
Please guide me how to achieve the desired use case.
Thanks in advance
I think you sfs_job_id create as UUID and use sfs_job_id usage anywhere are the same and unique.
`def save(self, *args, **kwargs):
if self.sfs_job_id is None:
self.sfs_job_id = 'SFS-' + self.sfs_job_start_date_time.isoformat()
return super(sfs_job_model, self).save(*args, **kwargs)`
I've a url for checking books by its id:
path('book/<int:book_id>', views.book, name='book'),
view:
def book(request, book_id):
book = get_object_or_404(Book, pk=book_id)
context = {
'book': book
}
return render(request, 'media/book.html', context)
but my client asked me to change it for the title instead but I tried it and it didn't seem to work, there are no examples for it in the docs either.
The NOTE in the answer above does not take SEO into account. For SEO purposes, it is much better to have a url that includes the name of the book rather than just the ID. If you are already in production, then remember to do a permanent redirect in your view from all ID-based urls to the slug-based url. Your Book model definition (or Product or whatever you've called it) should include a slugified field:
class Book(models.Model):
name = models.CharField(...)
slug = models.CharField(max_length=255, default='', unique=True, blank=True)
other_fields...
def save(self, *args, **kwargs):
# Create slug for SEO
#Don't ever change once established since is part of the URI
if self.slug is None or self.slug == '':
self.slug = slugify(self.name)
super(Book, self).save(*args, **kwargs)
You need to change the url to 'book/<str:book_title>', and also adjust your function accordingly:
def book(request, book_title):
book = get_object_or_404(Book, yourfieldfortitle=book_title)
...
It might be helpful to try accessing the url first with a pattern that you know must work. NOTE: this makes the strong assumption that a book is identified by its title, otherwise using the primary key is the proper way even if it doesn't "look nice" as a url.