I'm trying to do a simple commenting app that composed of a title and comments under that title. I can create title and I can see the form for adding comment entries to this title. I type and click submit and it does nothing. When I use admin panel, I can add entries without a problem.
This is my models:
class Baslik(models.Model):
user = models.ForeignKey(User, null=True, blank=True)
title = models.CharField(max_length=50)
slug = models.SlugField()
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return str(self.title)
def get_absolute_url(self, ):
return reverse('baslik', args=[self.slug])
class Entry(models.Model):
user = models.ForeignKey(User, null=True, blank=True)
baslik = models.ForeignKey(Baslik, null=True, blank=True)
icerik = models.TextField(max_length=50000)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self):
return str(self.icerik)
this is my views' entry part:
def tek(request, slug):
baslik = Baslik.objects.get(slug=slug)
entryler = baslik.entry_set.all()
form2 = EntryForm(request.POST or None)
if form2.is_valid():
entry = form2.save(commit=False)
entry.user = request.user
entry.save()
return HttpResponseRedirect('/baslik/%s'%(baslik.slug))
return render_to_response("baslik/tek.html", locals(), context_instance=RequestContext(request))
this is my forms.py:
class BaslikForm(ModelForm):
class Meta:
model = Baslik
fields = ('title',)
class EntryForm(ModelForm):
class Meta:
model = Entry
fields = ('icerik',)
this is my admin.py:
class EntryInline(admin.TabularInline):
model = Entry
class BaslikAdmin(admin.ModelAdmin):
list_display = ('__unicode__','live_link')
search_fields = ['title']
list_filter = ['timestamp', 'updated']
prepopulated_fields = {"slug": ('title',)}
readonly_fields = ['live_link', 'timestamp', 'updated']
inlines = [EntryInline]
class Meta:
model = Baslik
def live_link(self,obj):
link = "<a href='/baslik/" + str(obj.slug)+ "/'>" + obj.title + "<a/>"
return link
live_link.allow_tags = True
admin.site.register(Baslik, BaslikAdmin)
What should I do to solve this? Please be explanatory. I'm very new at Django.
Thanks.
Related
I have two models with imageFields, and want to have the same images there, to display them at the admin-page...
My two models:
class Produkt(models.Model):
STATUS_CHOICES = (
('draft', 'offline'),
('published', 'online'),
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique_for_date='publish')
image = models.ImageField(upload_to='images', height_field=None, width_field=None, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='published')
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
objects = models.Manager()
published = PublishedManager()
def get_absolute_url(self):
return reverse('app:produkt_detail', args=[self.publish.year, self.publish.month, self.publish.day, self.slug])
tags = TaggableManager()
class Bestellung(models.Model):
def two_week_hence():
return timezone.now() + timezone.timedelta(weeks=2)
produkt = models.ForeignKey(Produkt, on_delete=models.CASCADE, related_name='bestellung')
def get_image(self):
return self.produkt.image
versand_bis = models.DateTimeField(default=two_week_hence)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ('created',)
def __str__(self):
return f'hat Produkt {self.produkt} bestellt'
and my admin.py looks like this:
#admin.register(Produkt)
class ProduktAdmin(admin.ModelAdmin):
def image_tag(self, obj):
return format_html('<img height="100" src="{}" />'.format(obj.image.url))
image_tag.short_description = 'Image'
list_display = ('title', 'image_tag', 'image', 'kategorie', 'price', 'publish', 'status')
list_filter = ('created', 'publish', 'status', 'price',)
search_fields = ('title',)
prepopulated_fields = {'slug': ('title',)}
date_hierarchy = 'publish'
#admin.register(Bestellung)
class BestellungAdmin(admin.ModelAdmin):
def image_tag(self, obj):
return format_html('<img height="100" src="{}" />'.format(obj.get_image.url))
image_tag.short_description = 'Image'
list_display = ('produkt', 'image_tag', 'versand_bis', 'created', 'active')
list_filter = ('active', 'versand_bis', 'created', 'updated')
raw_id_fields = ('produkt',)
ordering = ('versand_bis',)
but the problem is, when I try to save an "Bestellung" on the admin page, I'm getting following error:
AttributeError
'function' object has no attribute 'url'
I'm new to django... :)
serializers.py
class RegSerializer(serializers.ModelSerializer):
admin = serializers.SlugRelatedField(slug_field='username', read_only=True)
class Meta:
model = Registration
fields = [
'id', 'rooms', 'first_name', 'last_name','admin', 'pasport_serial_num', 'birth_date', 'img', 'visit_date',
'leave_date', 'guest_count', 'room_bool']
models.py
class Rooms(models.Model):
objects = None
room_num = models.IntegerField(verbose_name='Комната')
room_bool = models.BooleanField(default=True, verbose_name='Релевантность')
category = models.CharField(max_length=150, verbose_name='Категория')
price = models.IntegerField(verbose_name='Цена (сум)', null=True)
def __str__(self):
return f'{self.room_num}'
class Meta:
verbose_name = 'Комнату'
verbose_name_plural = 'Комнаты'
class Registration(models.Model):
objects = None
rooms = models.ForeignKey(Rooms, on_delete=models.CASCADE, verbose_name='Номер',
help_text='Номер в который хотите заселить гостя!',
)
first_name = models.CharField(max_length=150, verbose_name='Имя')
last_name = models.CharField(max_length=150, verbose_name='Фамилия')
admin = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Администратор')
pasport_serial_num = models.CharField(max_length=100, verbose_name='Серия паспорта', help_text='*AB-0123456')
birth_date = models.DateField(verbose_name='Дата рождения')
img = models.FileField(verbose_name='Фото документа', help_text='Загружайте файл в формате .pdf')
visit_date = models.DateField(
default=django.utils.timezone.localdate, verbose_name='Дата прибытия')
leave_date = models.DateField(blank=True, null=True, verbose_name='Дата отбытия', default='После ухода!')
guest_count = models.IntegerField(default=1, verbose_name='Кол-во людей')
room_bool = models.BooleanField(default=False, verbose_name='Релевантность',
help_text='При бронирование отключите галочку')
price = models.IntegerField(verbose_name='Цена (сум)', null=True)
def __str__(self):
return f'{self.rooms},{self.last_name},{self.first_name},{self.room_bool}'
class Meta:
verbose_name = 'Номер'
verbose_name_plural = 'Регистрация'
how can I make it so that the name of the user who registered room is indicated in the admin field and without the right to change only readonly?
can this be done at all?
thanks in advance for your reply
You can pass additional attributes to serilizer's save method. In your view, you can call serializer save() with admin argument like this:
def your_view(request):
# your code
serializer.save(admin=request.user)
Or if you want to do it on admin page, you can override your admin's save_model method. Also you should specify admin as a readonly:
class RegistrationAdmin(admin.ModelAdmin):
readonly_fields = ('admin',)
def save_model(self, request, obj, form, change):
if not obj.pk:
# Only set admin during the first save.
obj.admin = request.user
super().save_model(request, obj, form, change)
I set serializers.HiddenField and by default set CurrentUserDefault() from serializers
automatically substitutes the value of the current admin and at the same time the admin field now goes to the api
class RegSerializer(serializers.ModelSerializer):
admin = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = Registration
exclude = ['price', 'visit_date']
When writing a comment under the article, it becomes possible to
choose which post to bring the comment to. How to make comments
automatically attach to the post under which it is written.
**views.py**
class AddCommentView(CreateView):
model = Comment
template_name = 'main/post_detail.html'
form_class = CommentForm
#fields = '__all__'
success_url = reverse_lazy('barbers')
**models.py**
class Post(models.Model):
photo = models.ImageField(upload_to='media/photos/',null=True, blank=True)
name_barber = models.CharField(max_length=30, null=True, blank=True)
description = models.TextField()
def __str__(self):
return self.description[:10]
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=30)
body = models.TextField(null=True)
add_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.post, self.name)
**forms.py**
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ( 'post', 'name', 'body')
You can remove the post field from the CommentForm:
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ('name', 'body')
In the path, you specify the primary key of the post to bind the comment to:
path('<int:post_pk>/comment', AddCommentView.as_view(), name='comment')
then in the AddCommentView, you can link the object to the post represented by this primary key in the .form_valid(…) method [Django-doc]:
class AddCommentView(CreateView):
model = Comment
template_name = 'main/post_detail.html'
form_class = CommentForm
success_url = reverse_lazy('barbers')
def form_valid(self, form):
form.instance.post_id = self.kwargs['post_pk']
return super().form_valid(form)
I've two model. I would like to save data from ForeignKey model. I'm created a modelform and save with my main foreignkey model. But I got this error ValueError at /c/customer/1/
Cannot assign "'1'": "BillingData.customer" must be a "CustomerData" instance.
I created Django model form and hocked up with view.
models.py file
class CustomerData(models.Model):
customer_name = models.CharField(max_length=100)
customer_no = models.CharField(max_length=100, default='', blank=True)
mobile_number = models.IntegerField()
alternative_phone = models.IntegerField(null=True, blank=True)
union_name = models.ForeignKey(UnionName, on_delete=models.SET_NULL, null=True)
word_name = models.ForeignKey(UnionWordName, on_delete=models.SET_NULL, null=True)
full_address = models.CharField(max_length=200, null=True, blank=True)
create_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s, Mobile: %s' % (self.customer_name, self.mobile_number)
def get_absolute_url(self):
return reverse('customer_data', kwargs={'pk': self.pk})
class BillingData(models.Model):
bill_no = models.CharField(max_length=100, default='', blank=True)
customer = models.ForeignKey(CustomerData, on_delete=models.CASCADE)
sales_person = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
customer_money = models.IntegerField()
create_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s %s' % (self.customer.customer_name, self.create_date.date())
def get_absolute_url(self):
return reverse('customers.views.BillingPage', kwargs={'pk': self.pk})
forms.py file
class BillCreateForms(forms.ModelForm):
bill_no = forms.CharField(max_length=100)
customer = forms.ChoiceField(choices=[(x.id, x.customer_name) for x in CustomerData.objects.all()])
customer_money = forms.IntegerField()
def save(self, commit=True):
instance = super(BillCreateForms, self).save(commit=False)
customer_pk = self.cleaned_data['customer']
instance.customer = CustomerData.objects.get(pk=customer_pk)
instance.save(commit)
return instance
class Meta:
model = BillingData
fields = ('bill_no', 'customer', 'customer_money',)
views.py file
class CustomerDataView(FormMixin, generic.DetailView):
model = CustomerData
form_class = BillCreateForms
template_name = "customers/customerdata_detail.html"
print(form_class)
success_url = '/c/'
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
I expect data save with foreignkey relation data. But doesn't save here.
You can't fix this problem in the save method, because the error happens before it gets that far.
You should be using a ModelChoiceField, not a ChoiceField. Not only would this fix the problem, it would also let you remove your entire save method.
customer = forms.ModelChoiceField(queryset=CustomerData.objects.all())
Change this line
instance.customer = CustomerData.objects.get(pk=customer_pk)
to
instance.customer_id = CustomerData.objects.get(pk=customer_pk).pk
Model:
class Blog(models.Model):
# ...
pass
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)
Set object
b = Blog.objects.get(id=1)
e = Entry.objects.get(id=234)
b.entry_set.add(e)
I can be able to add the first data entry but after that editing the existing data or adding the new data causes MultiValueDictKeyError at /admin/api/digitalpost/9b763eae-cb8b-4473-af5d-5d4d91323ae1/change/
"u'contentlist_set-0-basemodel_ptr'".
Models.py
class BaseModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
version = models.FloatField(default=1.0)
created_at = models.DateTimeField(auto_now_add=True)
def image_tag(self):
self.url = 'http://127.0.0.1:8000/' + self.picture.name
return u'<img src="%s" />' % self.picture.url
image_tag.short_description = 'Thumbnail'
image_tag.allow_tags = True
class Client(BaseModel):
parent = models.ForeignKey('self',on_delete=models.SET_NULL, blank=True, null=True, related_name='brands')
name = models.CharField(max_length=120, unique=True)
picture = models.ImageField(upload_to="static/images/digital")
list_display = ('name','parent',)
description = models.CharField(max_length=250)
def __unicode__(self):
if self.parent:
return "{} {}".format(self.parent.name, self.name)
else:
return self.name
def parent_brand(self):
return str(self)
parent_brand.short_description = 'NAME'
class Meta:
ordering = ['parent__name','name']
class Category(BaseModel):
title = models.CharField(max_length=64, unique=64)
description = models.CharField(max_length=256, null=True, blank=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
verbose_name_plural = "categories"
class DigitalPost(BaseModel):
title = models.CharField(max_length=100)
brand = models.ForeignKey(Client, on_delete=models.SET_NULL, blank=True, null=True, )
launch_date = models.DateField(blank=True, null=True)
order = models.IntegerField()
def __unicode__(self):
return self.title
class Meta:
ordering = ['order']
class ContentList(BaseModel):
title = models.CharField(max_length=100)
description = models.CharField(max_length=256, null=True, blank=True)
picture = models.ImageField(upload_to="static/images/digital", blank=True)
post = models.ForeignKey(DigitalPost, on_delete=models.SET_NULL, null=True, blank=True)
# post_category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
admin.py
class ContentListForm(forms.ModelForm):
class Meta:
model = models.ContentList
fields = '__all__'
class ContentListInline(admin.TabularInline):
model = models.ContentList
form = ContentListForm
fk_name = 'post'
exclude = ('id', 'version')
class DigitalPostForm(forms.ModelForm):
class Meta:
model = models.DigitalPost
fields = '__all__'
#admin.register(models.DigitalPost)
class DigitalPostAdmin(ActiveStaffPermittedModel):
inlines = [
ContentListInline,
]
form = DigitalPostForm
actions = ['delete_selected']
exclude = ('id', 'version',)
readonly_fields = ('created_at',)
def delete_selected(self, request, obj):
for o in obj.all():
self.delete_one(request, o)
delete_selected.short_description = "Delete selected Posts"