This is my model:
def group_based_upload_to(instance, filename):
return "media/image/lavorazione/{}".format(instance.prestazione.id,)
class ImmaginiLavorazioni(models.Model):
immagine = models.ImageField(upload_to=group_based_upload_to)
prestazione = models.ForeignKey(Listino, on_delete=models.SET_NULL, null=True,
blank=True, default=None, related_name='Listino3')
and my form:
class ImmagineUploadForm(forms.ModelForm):
class Meta:
model = ImmaginiLavorazioni
exclude = ('preventivo', )
I need a view to save an image in a specific path.
The name of path must be the pk of foreign key.
How can I do that?
I use a model of how a blog post works. You can adjust the example on your needs. You should try and avoid saving the location path from a view.
On your models.py:
# Create your models here.
def upload_location(instance, filename):
filebase, extension = filename.split(".")
return "%s/%s" % (instance.id, filename)
class Post(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to=upload_location,
null=True,
blank=True,
height_field="height_field",
width_field="width_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = HTMLField()
formfield_overrides = {
models.TextField: {'widget': AdminPagedownWidget },
}
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
On your forms.py:
from django import forms
from pagedown.widgets import PagedownWidget
from pagedown.widgets import AdminPagedownWidget
from .models import Post
class PostForm(forms.ModelForm):
content = forms.CharField(widget=PagedownWidget(show_preview=False))
class Meta:
model = Post
fields = [
"title",
"content",
"image"
]
class PostModelForm(forms.ModelForm):
content = forms.CharField(widget=AdminPagedownWidget())
class Meta:
model = Post
fields = '__all__'
And on your settings.py:
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media_cdn")
Here is your view.py:
# Create your views here.
def post_create(request):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
form = PostForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, "Succefully Created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
return render(request, "post_form.html", context)
The next code has an example without form but you can modify based on your needs.
Below the settings.py
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, '../media')
Firstable, I defined the path of the image in the helpers.py
from django.conf import settings
from datetime import datetime
def upload_to_image_post(self, filename):
"""
Stores the image in a specific path regards to date
and changes the name of the image with for the name of the post
"""
current_date = datetime.now()
return '%s/posts/main/{year}/{month}/{day}/%s'.format(
year=current_date.strftime('%Y'), month=current_date.strftime('%m'),
day=current_date.strftime('%d')) % (settings.MEDIA_ROOT, filename)
You could define the image's name with some code like this one. But you have to regard you should have the pk to replace the name of the image
ext = filename.split('.')[-1]
name = self.pk
filename = '%s.%s' % (name, ext)
So, I called the def in my models.py, specifically in the image's field
from django.db import models
from django.utils.text import slugify
from .helpers import upload_to_image_post
class Post(models.Model):
"""
Store a simple Post entry.
"""
title = models.CharField('Title', max_length=200, help_text='Title of the post')
body = models.TextField('Body', help_text='Enter the description of the post')
slug = models.SlugField('Slug', max_length=200, db_index=True, unique=True, help_text='Title in format of URL')
image_post = models.ImageField('Image', max_length=80, blank=True, upload_to=upload_to_image_post, help_text='Main image of the post')
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
I hope this helped you
Now this is my models:
def group_based_upload_to(instance, immagine):
return "media/preventivo/{pk}/{image}".format(pk=instance.preventivo.id, image=immagine)
class ImmaginiLavorazioni(models.Model):
immagine = models.ImageField(upload_to=group_based_upload_to)
preventivo = models.ForeignKey(Preventivo, on_delete=models.SET_NULL, null=True, blank=True,
default=None, related_name='Listino3')
And this is my view:
def upload_immagine(request, pk):
member = get_object_or_404(Preventivo, pk=pk)
if request.method == 'POST':
form = ImmagineUploadForm(request.POST or None, request.FILES or None)
if form.is_valid():
newimmagine = form.save(commit=False)
newimmagine.preventivo_id = member.pk
newimmagine.save()
return redirect('preventivo_new2', pk=member.pk)
else:
form = ImmagineUploadForm(request.POST or None, request.FILES or None)
return render(request, 'FBIsystem/upload_immagine.html', {'member': member, 'form': form})
It save in db the file path and the foreign key like:
immagine= media/preventivo/6/image.jpg
preventivo_id = 6
but not create a folder and not save the uploaded image...
Related
I have a form that gets some fields and tags from users and save the user input data in database:
By the way I am using taggit
this is my model:
from taggit.managers import TaggableManager
class Question(models.Model):
title = models.CharField(max_length=500)
name = models.CharField(max_length=50, default=None)
slug = models.SlugField(max_length=500, unique_for_date='created', allow_unicode=True)
body = models.TextField(max_length=2000)
created = models.DateTimeField(auto_now_add=True)
tags = TaggableManager()
def get_absolute_url(self):
return reverse("questions:question_detail", args=[self.created.year, self.created.month, self.created.day, self.slug])
def __str__(self):
return self.title
and here is my view:
def question_form(request):
new_question = None
if request.method == 'POST':
question_form = QuestionForm(data=request.POST)
if question_form.is_valid():
new_question = question_form.save(commit=False)
new_question.slug = slugify(new_question.title)
new_question.save()
question_form.save_m2m()
else:
question_form = QuestionForm()
return render(request,
'questions/que/form.html',
{'question_form':question_form, 'new_question':new_question})
and my form.py is like this:
from taggit.forms import TagField
class QuestionForm(ModelForm):
class Meta:
model = Question
fields = ('name', 'title', 'body',)
tags = TagField()
my problem is when user enters the tags and other fields everything is saved in database except the tags! Can anyone help me?
i am saving a form with a filefield, and saying upload_to to a user_path from the userprofile. I do not know how to write the view for the form
models.py
def nice_user_folder_upload(instance, filename):
extension = filename.split(".")[-1]
return (
f"{instance.UserProfile.Assigned_Group}/{filename}"
)
class Metadataform(models.Model):
id = models.AutoField(primary_key=True)
Authors_Name = models.CharField(max_length=500, blank=True, null=True)
Document = models.FileField(upload_to=nice_user_folder_upload)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Assigned_Group= models.CharField(max_length=500, choices=Group_choices, default='Please Select')
def __str__(self):
return self.user.username
views.py
def Metadata_submission(request):
Authors_Name = request.POST["Authors_Name"]
if request.method == 'POST':
form = Fileuploadform(request.POST, request.FILES)
if form.is_valid():
form.save()
return render(request, "home.html")
else:
form = Fileuploadform()
# forms.py
class Fileuploadform(forms.ModelForm):
class Meta:
model = Metadataform
fields = ['Authors_Name','Affliations','Dataset_Creation_Date','Publication_Ref','Embargo_Time','DataGeneration_Type','Methods','Instruments','Software','Models','Device','Configuration','Precursor','Data_Type','Variables','Error_Estimation','Document']
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('Assigned_Group',)
i am getting an AttributeError at /Metadata_submission/
'Metadataform' object has no attribute 'UserProfile'
The problem here I think is you have so many fields here that might not be associated with your Metadataform model (Maybe you haven't posted it in full). I think you should consider reading doc. By the look of it, you are trying to add UserProfile somewhere on your form, which is causing the error.
I would like to get access to fields of the InlineFormSet for consumption into the View.
Here is an example based on https://django-extra-views.readthedocs.io/en/latest/views.html#createwithinlinesview-and-updatewithinlinesview:
from extra_views import InlineFormSet, CreateWithInlinesView,
class ItemsInline(InlineFormSet):
model = Item
class TagsInline(InlineFormSet):
model = Tag
class OrderCreateView(CreateWithInlinesView):
model = Order
inlines = [ItemsInline, TagsInline]
def get_success_url(self):
return self.object.get_absolute_url()
How do I expose the InlineFormSet fields in the get_context_data() and forms_valid() methods?
Warning: Code below fails!
class OrderCreateView(CreateWithInlinesView):
[... see above ...]
def get_context_data(self, **kwargs):
context = super(OrderCreateView, self).get_context_data(**kwargs)
if self.request.POST:
context['items'] = ItemsInline(self.request.POST)
context['tags'] = TagsInline(self.request.POST)
else:
context['items'] = ItemsInline()
context['tags'] = TagsInline()
return context
def forms_valid((self, form, inlines):
[...]
return super(OrderCreateView, self).forms_valid(form, inlines)
I reproduced your example with this models:
STATUS_CHOICES = (
(0, 'Placed'),
(1, 'Charged'),
(2, 'Shipped'),
(3, 'Cancelled'),
)
class Order(models.Model):
name = models.CharField(max_length=255)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
action_on_save = models.BooleanField(default=False)
class Item(models.Model):
item_name = models.CharField(max_length=255)
sku = models.CharField(max_length=13)
price = models.DecimalField(decimal_places=2, max_digits=12, db_index=True)
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
status = models.SmallIntegerField(default=0, choices=STATUS_CHOICES, db_index=True)
date_placed = models.DateField(default=now, null=True, blank=True)
def __unicode__(self):
return '%s (%s)' % (self.item_name, self.sku)
class Tag(models.Model):
tag_name = models.CharField(max_length=255)
content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
def __unicode__(self):
return self.tag_name
Urls:
from django.conf.urls import url
from .views import OrderCreateView, OrderUpdateView
urlpatterns = [
url(r'^inlines/new/$', OrderCreateView.as_view()),
url(r'^inlines/(?P<pk>\d+)/$', OrderUpdateView.as_view()),
]
Forms:
from django import forms
from .models import Order, Item
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['name']
def save(self, commit=True):
instance = super(OrderForm, self).save(commit=commit)
if commit:
instance.action_on_save = True
instance.save()
return instance
class ItemForm(forms.ModelForm):
flag = forms.BooleanField(initial=True)
class Meta:
model = Item
fields = ['item_name', 'sku', 'price', 'order', 'status']
Views:
from django.contrib.contenttypes.models import ContentType
from extra_views import InlineFormSet, CreateWithInlinesView, UpdateWithInlinesView
from extra_views.generic import GenericInlineFormSet
from .forms import OrderForm
from .models import Item, Order, Tag
class ItemsInline(InlineFormSet):
model = Item
fields = ['item_name', 'sku', 'price', 'order', 'status']
class TagsInline(GenericInlineFormSet):
model = Tag
fields = ['tag_name']
class OrderCreateView(CreateWithInlinesView):
model = Order
fields = ['name']
context_object_name = 'order'
inlines = [ItemsInline, TagsInline]
template_name = 'extra_views/order_and_items.html'
def get_success_url(self):
return '/inlines/%i' % self.object.pk
class OrderUpdateView(UpdateWithInlinesView):
model = Order
form_class = OrderForm
inlines = [ItemsInline, TagsInline]
template_name = 'extra_views/order_and_items.html'
def get_success_url(self):
return ''
In OrderCreateView you cannot read Tag and Item records in the
get_context_data method because they haven't been created.
In OrderCreateView you can read all records after the forms_valid
method as usual.
In OrderUpdateView you can read all records in the
get_context_data method like in the forms_valid method.
It looks like this:
class OrderCreateView(CreateWithInlinesView):
# ...
def get_context_data(self, **kwargs):
data = super(OrderCreateView, self).get_context_data(**kwargs)
from pprint import pprint
pprint(self.request.POST) # there is only post data here
return data
def forms_valid(self, form, inlines):
instance = super(OrderCreateView, self).forms_valid(form, inlines)
ct = ContentType.objects.get_for_model(self.model)
print('all items', [item.item_name for item in self.object.items.all()]) # items
print('all tags', [tag.tag_name for tag in
TagsInline.model.objects.filter(content_type=ct, object_id=self.object.id)]) # tags
return instance
class OrderUpdateView(UpdateWithInlinesView):
# ...
def get_context_data(self, **kwargs):
context = super(OrderUpdateView, self).get_context_data(**kwargs)
ct = ContentType.objects.get_for_model(self.model)
print('all items', [item.item_name for item in self.object.items.all()]) # items
print('all tags', [tag.tag_name for tag in
TagsInline.model.objects.filter(content_type=ct, object_id=self.object.id)]) # tags
return context
I have an Ourteam App that allows you to upload an image, name, title, and social media information for employees. Whenever I create an object the "default.jpg" file is deleted from the media_root.
This is my model:
from django.db import models
from cms.models.pluginmodel import CMSPlugin
from django.utils.translation import ugettext_lazy as _
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
from django.template.defaultfilters import slugify
class Employee(CMSPlugin):
# Set Name
name = models.CharField(_('name'), max_length=48)
# Define Slug
slug = models.SlugField(max_length=40, null = False, blank = True)
# Set Title
title = models.CharField(_('title'), max_length=48)
# Set Image upload path and image properties
image_upload_path = 'ourteam/%Y/%m/%d'
image = fields.ImageField(upload_to=image_upload_path,
blank=True, default='ourteam/default.jpg',
dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 150, 'max_height': 150}))
])
created = models.DateTimeField(_('created'), auto_now_add=True)
email = models.EmailField(_('email'), max_length=254)
# Social Media
twitter = models.CharField(_('twitter'), max_length=24, blank=True, default='https://www.twitter.com')
linkedin = models.CharField(_('linkedin'), max_length=24,blank=True, default='https://www.linkedin.com')
facebook = models.CharField(_('facebook'), max_length=24,blank=True, default='https://www.facebook.com')
class Meta:
verbose_name = _('employee')
verbose_name_plural = _('employee')
db_table = 'employee'
ordering = ('-created',)
get_latest_by = 'created'
def __unicode__(self):
return u'%s' % self.title
def __str__(self):
return self.name
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Employee, self).save(*args, **kwargs)
def get_all_employees():
all_entries = Employee.objects.all().order_by('created')
return all_entries
def slug(sluggy):
sluggy = sluggy.replace(' ', '-').lower()
return slugify(sluggy)
You should try with that :
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)
I'm making an forum using this tutorial http://lightbird.net/dbe/forum2.html and I encountered an error .
When I click edit profile , it suppose to point to this page instead I get an error(below)
DoesNotExist at /forum/profile/1/
UserProfile matching query does not exist.
Request Method: GET
Request URL: http://127.0.0.1:8000/forum/profile/1/
Django Version: 1.4.3
Exception Type: DoesNotExist
Exception Value:
UserProfile matching query does not exist.
Traceback Switch to copy-and-paste view
C:\djcode\mysite\forum\views.py in profile
profile = UserProfile.objects.get(user=pk)
I think this error mean , django can't receive my admin login .
This is part of my fbase.html
Edit profile
which point to my URLconf.
from django.conf.urls import patterns,include,url
from django.contrib import admin
from django.conf import settings
urlpatterns = patterns('forum.views',
url(r'^$','main',name='main'),
url(r"^forum/(\d+)/$", "forum",name ="forum"),
url(r"^thread/(\d+)/$","thread",name = "thread"),
url(r"^post/(new_thread|reply)/(\d+)/$", "post",name = "post"),
url(r"^reply/(\d+)/$", "reply" , name ="reply"),
url(r"^new_thread/(\d+)/$", "new_thread" , name ="new_thread"),
url(r"^profile/(\d+)/$", "profile",name= "profile"),
)
and into my view function
def profile(request, pk):
"""Edit user profile."""
profile = UserProfile.objects.get(user=pk)
img = None
if request.method == "POST":
pf = ProfileForm(request.POST, request.FILES, instance=profile)
if pf.is_valid():
pf.save()
# resize and save image under same filename
imfn = pjoin(MEDIA_ROOT, profile.avatar.name)
im = PImage.open(imfn)
im.thumbnail((160,160), PImage.ANTIALIAS)
im.save(imfn, "JPEG")
else:
pf = ProfileForm(instance=profile)
if profile.avatar:
img = "/media/" + profile.avatar.name
return render_to_response("forum/profile.html", add_csrf(request, pf=pf, img=img))
This is my models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
from string import join
from mysite.settings import MEDIA_ROOT
class Forum(models.Model):
title = models.CharField(max_length=60)
def __unicode__(self):
return self.title
def num_posts(self):
return sum([t.num_posts() for t in self.thread_set.all()])
def last_post(self):
if self.thread_set.count():
last = None
for t in self.thread_set.all():
l = t.last_post()
if l:
if not last: last = l
elif l.created > last.created: last = l
return last
class Thread(models.Model):
title = models.CharField(max_length=60)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(User, blank=True, null=True)
forum = models.ForeignKey(Forum)
def __unicode__(self):
return unicode(self.creator) + " - " + self.title
def num_posts(self):
return self.post_set.count()
def num_replies(self):
return self.post_set.count() - 1
def last_post(self):
if self.post_set.count():
return self.post_set.order_by("created")[0]
class Post(models.Model):
title = models.CharField(max_length=60)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(User, blank=True, null=True)
thread = models.ForeignKey(Thread)
body = models.TextField(max_length=10000)
def __unicode__(self):
return u"%s - %s - %s" % (self.creator, self.thread, self.title)
def short(self):
return u"%s - %s\n%s" % (self.creator, self.title, self.created.strftime("%b %d, %I:%M %p"))
short.allow_tags = True
### Admin
class ForumAdmin(admin.ModelAdmin):
pass
class ThreadAdmin(admin.ModelAdmin):
list_display = ["title", "forum", "creator", "created"]
list_filter = ["forum", "creator"]
class PostAdmin(admin.ModelAdmin):
search_fields = ["title", "creator"]
list_display = ["title", "thread", "creator", "created"]
class UserProfile(models.Model):
avatar = models.ImageField("Profile Pic", upload_to="images/", blank=True, null=True)
posts = models.IntegerField(default=0)
user = models.ForeignKey(User, unique=True)
def __unicode__(self):
return unicode(self.user)
You forgot to put pk in your render:
return render_to_response("forum/profile.html", add_csrf(request, pf=pf, 'profile': profile, img=img))
In html:
Edit profile