It is necessary to place posts on the site so that they can be created and edited, but in the site design the posts are separated by sliders and other elements, how is it possible to implement this in such a way that the other layout elements are, so to speak, ignored?
I tried to solve this problem by creating additional models, that is, the posts before the separating elements (sliders in this case) should be taken in one class, and the subsequent ones in another and further edited in such a way. Of course this is a crutch, but I don’t know how to configure it, because together these models are not displayed for me, that is, either one or the other. I also created a separate class for the Main Post, because it has a different design and, as a matter of fact, always hangs in the top, but of course it’s ideal to implement such that the model has such an attribute that you can indicate to a specific post that it is the main and most located at the beginning of the site.
Here is my code (let's say that we added Posts_one, Posts_two, if we talk about the case of using a crutch, which I also failed):
models.py:
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Toppost(models.Model):
title = models.CharField(max_length=200)
caption = models.CharField(max_length=150, default='краткое описание поста')
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=200)
caption = models.CharField(max_length=150, default='краткое описание поста')
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
views.py:
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Post, Toppost
def posts_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/posts_list.html', {'posts': posts})
topposts = Toppost.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/posts_list.html', {'topposts': topposts})
I also attach a screenshot with a diagram of how it should look. Ideally, of course, it’s interesting to know how this can be implemented so that all this is one Post model and does not destroy the layout of the site and that you can select any post as Main_Post.
I'd simply add an attribute for a post to define whether it's a top post or not.
class Post(models.Model):
# ... all the other stuff ...
is_top_post = models.BooleanField(default=False)
# ... all the other stuff ...
# ...
def posts_list(request):
all_posts = Post.objects.filter(published_date__lte=timezone.now()).order_by("published_date")
non_top_posts = []
top_posts = []
for post in all_posts:
(top_posts if post.is_top_post else non_top_posts).append(post)
return render(request, "blog/posts_list.html", {"posts": non_top_posts, "top_posts": top_posts})
You can also ensure that there is exactly one top post by adding a save override like
class Post(models.Model):
# ... all the other stuff ...
is_top_post = models.BooleanField(default=False)
# ... all the other stuff ...
def save(self, **kwargs):
if self.is_top_post:
# Un-top every other post
Post.objects.exclude(id=self.id).update(is_top_post=False)
return super().save(**kwargs)
Related
this is my model
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=256)
text = models.TextField()
create_date = models.DateTimeField(auto_now_add=True, auto_now=False)
published_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return f'{self.author} --> {self.title}'
def get_absolute_url(self):
return reverse('blog:post_detail', kwargs={'pk': self.pk})
def publish(self):
self.published_date = timezone.now()
self.save()
def unpublish(self):
self.published_date = None
self.save()
and i registered it on Django admin. i have created two post on Django admin, the new post when i publish it and hit now and refresh the page, it won't show this post:
this is admin code:
from django.contrib import admin
from .models import Post, Comment
#admin.register(Post, Comment)
class PostModelAdmin(admin.ModelAdmin):
pass
this is the view:
class PostListView(ListView):
queryset = Post.objects.filter(published_date__lte=timezone.now())
print('query0: ', queryset)
def get_queryset(self):
queryset = super().get_queryset()
print('query1: ', queryset)
print('query2:', self.queryset)
print('query3: ', Post.objects.filter(published_date__lte=timezone.now()))
return Post.objects.filter(published_date__lte=timezone.now())
As you can see result of query1, query2 is different with query3.
I think this is a bug, if it's not please light me up.
it's been answered by
Iain Shelvington in a comment:
The class attribute queryset defined in PostListView is created once when your app starts, it will always filter using the value of timezone.now() at the time when your app started. To test this, try restarting your app after publishing and see if the result changes
The problem:
I have a model, which is referencing the basic User model of django. Right now, if I submit the form Django updates my database by replacing the existing data with the new one. I want to be able to access both of them. (In weight and date field)
Models file:
I saw other posts here, where they solved a problem by specifying a foreign key, but that doesn't solve it for me.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
weight = models.FloatField(max_length=20, blank=True, null=True)
height = models.FloatField(max_length=20, blank=True, null=True)
date = models.DateField(auto_now_add=True)
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
Views file:
This is where I save the data that I get from my form called WeightForm
from django.shortcuts import render
from django.contrib.auth.models import User
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from users import models
from users.models import Profile
from .forms import WeightForm
def home(request):
form = WeightForm()
if request.is_ajax():
profile = get_object_or_404(Profile, id = request.user.id)
form = WeightForm(request.POST, instance=profile)
if form.is_valid():
form.save()
return JsonResponse({
'msg': 'Success'
})
return render(request, 'Landing/index.html',{'form':form})
What I tried:
I used to have a OneToOneField relation with this model, but as you can see I changed it to foreignkey, according to answers I saw on this site.
Thanks if you've gotten this far in my mess :D
I didn't understood exactly what you mean by "I want to be able to access both of them. (In weight and date field)" but I guess you want user to be able to see their previous data of weight and Date also, so you can try doing this:
In your models.py do try doing this,
class Profile(models.Model):
user_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
height = models.FloatField(max_length=20, blank=True, null=True)
def __str__(self):
return self.user.username
class UserData(models.Model):
Data_id = models.AutoField(primary_key=True)
user_id = models.ForeignKey(Profile, on_delete=models.CASCADE)
weight = models.FloatField(max_length=20, blank=True, null=True)
date = models.DateField(auto_now_add=True)
then u can have seperate forms for both the models and use them combined.
You can make a workaround
Create new model which would include something like "version"
Reference to version with foreign key
class ProfileChange(models.Model):
Date = models.DateField(default=datetime.datetime.today().strftime('%Y-%m-%d'))
#classmethod
def create(cls):
object = cls()
return object
class Profile(models.Model):
version = models.ForeignKey(ProfileChange,on_delete=models.CASCADE)
Unfortunately, you could see only one ProfileChange a day. If you want to see more of them, instead of models.DataField use models.IntegerField
I'm trying to create a subscription style service on Django (using Django3)
Basically, I had it working..ish, but my stripe customer keys weren't being added in, so I fiddled around to get that sorted.
Now I'm getting this error - Membership matching query does not exist. this is whenever I'm trying to create an account, login or login to the admin of my Django project.
I can't really figure out what the issue is, as I've reverted the changes I made to get the cust-Id (any tips here would be appreciated! lol) working again, but it's still throwing it up at me.
Here's my code in my models, I can't even pinpoint where this issue is coming from if I'm honest. (I got this mostly from the JustDjango tutorial btw!)
The debug thing is saying it's to do with the free_membership variable in the post_save_usermembership_create method though.
So far I just have models.py and admin.py done to get this up & running -
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from datetime import datetime
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
MEMBERSHIP_CHOICES = (
('Regular', 'reg'),
('Premium', 'premium'),
('Free', 'free')
)
class Membership(models.Model):
slug = models.SlugField()
membership_type = models.CharField(
choices=MEMBERSHIP_CHOICES,
default='Free',
max_length=30)
price = models.IntegerField(default=15)
stripe_plan_id = models.CharField(max_length=40)
def __str__(self):
return self.membership_type
class UserMembership(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
stripe_customer_id = models.CharField(max_length=40)
membership = models.ForeignKey(
Membership, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.user.username
def post_save_usermembership_create(sender, instance, created, *args, **kwargs):
user_membership, created = UserMembership.objects.get_or_create(
user=instance)
if user_membership.stripe_customer_id is None or user_membership.stripe_customer_id == '':
new_customer_id = stripe.Customer.create(email=instance.email)
free_membership = Membership.objects.get(membership_type='Free')
user_membership.stripe_customer_id = new_customer_id['id']
user_membership.membership = free_membership
user_membership.save()
post_save.connect(post_save_usermembership_create,
sender=settings.AUTH_USER_MODEL)
class Subscription(models.Model):
user_membership = models.ForeignKey(
UserMembership, on_delete=models.CASCADE)
stripe_subscription_id = models.CharField(max_length=40)
active = models.BooleanField(default=True)
def __str__(self):
return self.user_membership.user.username
UPDATE #2
Status: Still not solved
Updated: Thurs. Dec. 18, 11:30 a.m.
I'm currently using FullArticle.objects.order_by('?').first() to get a random article from my database, but it's not working. There is probably something missing from my models, view or url.py that's missing.
models.py
from django.db import models
from django.core.urlresolvers import reverse
# Create your models here.
class FullArticleQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
class FullArticle(models.Model):
title = models.CharField(max_length=150)
author = models.CharField(max_length=150)
slug = models.SlugField(max_length=200, unique=True)
pubDate = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
category = models.CharField(max_length=150)
heroImage = models.CharField(max_length=250, blank=True)
relatedImage = models.CharField(max_length=250, blank=True)
body = models.TextField()
publish = models.BooleanField(default=True)
gameRank = models.CharField(max_length=150, blank=True, null=True)
objects = FullArticleQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("FullArticle_detailed", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog entry"
verbose_name_plural = "Blog Entries"
ordering = ["-pubDate"]
views.py
from django.views import generic
from . import models
from .models import FullArticle
# Create your views here.
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
randomArticle = FullArticle.objects.order_by('?').first()
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns(
'',
url(r'^$', views.BlogIndex.as_view(), name="list"),
url(r'^(?P<slug>\S+)', views.BlogDetail.as_view(), name="detailed"),
)
Section in list.html that I want to be random
<div class="mainContent clearfix">
<div class="wrapper">
<h1>Top 10 Video Games</h1>
{% for article in object_list|slice:":1" %}
<p class="date">{{article.pubDate|date:"l, F j, Y" }}</p> | <p class="author">{{article.author}}</p>
<img src="{{article.heroImage}}" alt="" class="mediumImage">
<p class="caption">{{article.body|truncatewords:"80"}}</p>
{% endfor %}
I assume that FullArticle.objects.order_by('?')[0] will give me a
random item from my class of FullArticle. But, let's say that out of
my model, I only want data associated with the specific parts of the
article: title, author, heroImage and body. How would I go about doing
that?
To get specific fields of an object, use values or values_list. The first will return dictionaries, the second tuples:
FullArticle.objects.order_by('?').values('title','author','heroImage','body').first()
The above would result in something like:
{'title': 'Foo', 'author': 'Foo Author', ... }
I've also tacked on your suggestion of random =
FullArticle.objects.order_by('?')[0] called it "random" instead.
Not sure what this is about, but try to avoid shadowing built-in libraries, like random.
1) Actually you almost did it.
try:
article = FullArticle.objects.order_by('?')[0]
except IndexError:
article = None
2) You could use this in models.py as well as in views.py. IMHO there is no need to extract this string to separate method so I would write this code wherever I need it.
3) Better use ORM don't convert db result to list to choose first item. This is can be really memory and CPU expensive.
Getting a random article would usually be done in a view, or as a modelmanager method, or as a class method. Fullarticle.random should not be a class attribute. That will not work as you expect.
# Used in a view.
article = FullArticle.objects.order_by('?').first()
# you can also make a random() method in your model manager.
def random(self):
return self.get_queryset().order_by('?').first()
# or as a class method inside FullArticle
#classmethod
def random(cls):
return cls.objects.order_by('?').first()
I'm not quite sure what exactly you mean by this.
I only want data associated with the specific parts of the article: title, author, heroImage and body. How would I go about doing that?
To access specific attributes you do this:
title = article.title
author = article.author
If you don't need to use article.category, just don't access it.
from django.views.generic import DetailView
from books.models import Publisher, Book
To pass data from your (class based) View to the template it has to be added to the context.
Here's an example from the official documentation:
class PublisherDetail(DetailView):
model = Publisher
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(PublisherDetail, self).get_context_data(**kwargs)
# Add in a QuerySet of all the books
context['book_list'] = Book.objects.all()
return context
source: https://docs.djangoproject.com/en/1.7/topics/class-based-views/generic-display/#adding-extra-context
Lots of people find Class Based Views in Django to be a bit confusing. I would recommend that you understand how function based views work before you start doing anything complicated with CBVs.
In Django I'm trying to write a ModelForm for a ContactForm and when I try to load the page containing the form it says that it doesn't exist. Then when I try to render the other form I had previously written it says that
Caught AttributeError while rendering: 'CashtextsForm' object has no attribute 'subject'
'Subject' is a field in the form that I was trying to render in ContactForm. So is there some certain order I have to list them in models.py? Here's that code:
# Create your models here.
from django.db import models
from django.forms import ModelForm
class Cashtexts(models.Model):
cashTexts = models.CharField(max_length=100, blank=True) #change me to a website filter
superPoints = models.CharField(max_length=100, blank=True)#chance to "superPoints _Username"
varolo = models.CharField(max_length=100, blank=True)
swagbucks = models.CharField(max_length=100, blank=True)
neobux = models.CharField(max_length=100, blank=True)
topline = models.CharField(max_length=100, blank=True)
Paidviewpoint = models.CharField(max_length=100, blank=True)
cashcrate = models.CharField(max_length=100, blank=True)
def __unicode__(self):
return self.cashcode
class Contact(models.Model):
sender = models.EmailField()
subject = models.CharField(max_length=25)
message = models.TextField()
class CashtextsForm(ModelForm):
class Meta:
model = Cashtexts
def __unicode__(self):
return self.subject
class ContactForm(ModelForm):
class Meta:
model = Contact
I previously had them arranged as Model-Modelform, Model-Modelform but hereit shows them as the way I now currently have them.
Also Is there any advantages to write just forms? Right now I'm more comfortable writing model forms over forms(I dont imagine they are much differnt) but if I only wrote model forms would I be missing out on features? So is there anything I missed on how t write multiple forms in models.py or did I have them written worng? or can i not create them via the command syncdb?
The __unicode__(self) method should be part of your Contact class
class Contact(models.Model):
sender = models.EmailField()
subject = models.CharField(max_length=25)
message = models.TextField()
def __unicode__(self):
return self.subject
It doens't make sense inside CashtextsForm as that does not "know" a subject attribute.
Yes, your form really does not have subject, just remove __unicode__ definition and everything will be ok.
This is because of declarative style of django code. If you want to inspect your objects use pdb module and dir builtin.
You will use ModelForm subclasses almost every time, but sometimes you will need a form which can not be built from model. In this case django will help you to describe such form and to use form clean and field validation.
the subject field is defined in the model and not in the modelform, since a modelform can be initialized without a model instance it is not safe to do something like this:
def __unicode__(self):
return self.instance.subject
What you can do (but I do not really see the point of doing this):
def __unicode__(self):
if getattr(self, 'instance') is not None:
return self.instance.subject
return super(CashtextsForm, self).__unicode__()