将用户实例的表单限制为每天一次 (Django)

Ant*_*ony 2 python django

我正在开发这个网络应用程序,它允许人们登录,并能够创建:用户、创建啤酒和对不同类型啤酒的评论。

这是我用于创建啤酒的models.py:

from django.db import models
from django.conf import settings

# Models

User = settings.AUTH_USER_MODEL

class BeerModel(models.Model):

    user = models.ForeignKey(User, default=1)
    name = models.CharField(max_length=254, default="")
    style = models.CharField(max_length=254, default="")
    ibu = models.IntegerField(default="")
    calories = models.IntegerField(default="")
    abv = models.IntegerField(default="")
    location = models.CharField(max_length=254, default="")

    class Meta:
        verbose_name_plural = 'Beers'

    def __str__(self):
        return self.name

    def avg(self):
        return
Run Code Online (Sandbox Code Playgroud)

这是我的forms.py:

from django import forms
from django.contrib.auth.models import User
from .models import BeerModel, RateModel

# Forms

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ('username', 'email', 'password')
        help_texts = {
            'username': None,
        }

class NewBeerForm(forms.ModelForm):
    name = forms.CharField(label="Beer Name")
    ibu = forms.IntegerField(label="IBU")
    abv = forms.IntegerField(label="ABV")
    location = forms.CharField(label="Brewery Location")

    class Meta:
        model = BeerModel
        fields = '__all__'
Run Code Online (Sandbox Code Playgroud)

这是我的 views.py:

@login_required
def new_beer(request):
    if request.method == "POST":
        beer = NewBeerForm(request.POST)
        if beer.is_valid():
            beer.save(commit=True)
            return HttpResponseRedirect(reverse('beer_tracker:home'))
    else:
        beer = NewBeerForm()

    return render(request, 'beer_tracker/new_beer.html', {'beer':beer})
Run Code Online (Sandbox Code Playgroud)

如您所见,要创建啤酒,您需要填写一些详细信息,包括“用户”字段。

所以我的目标是能够限制我选择的特定用户每天只能创建一种啤酒。

有什么想法吗?我正在研究芹菜,但我相信有更好的方法。

安东尼

Pau*_*ida 5

您要做的第一件事是创建一个DateFieldin BeerModel

class BeerModel(models.Model):
    ...
    created = models.DateField(default=django.utils.timezone.now)
    # or (but see https://code.djangoproject.com/ticket/20180)
    # created = models.DateField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)

然后,如果要在数据库级别强制执行此操作,可以创建一个unique_together约束:

class BeerModel(models.Model):
    ...
    class Meta:
        unique_together = ('user', 'created')
Run Code Online (Sandbox Code Playgroud)

或者你可以clean在表单上有一个方法来检查这个:

class NewBeerForm(forms.ModelForm):
    ...
    def clean(self):
        cleaned_data = super().clean() 
        user = cleaned_data.get('user')
        created = datetime.now().date()           
        if BeerModel.objects.filter(user=user, created=created).exists():
            raise forms.ValidationError("User already created beer today")
Run Code Online (Sandbox Code Playgroud)

clean由于我上面提到的票(如果它仍然适用),您可能总是需要无论如何。如果您使用可编辑的日期字段,则必须确保将当前日期保存到数据库中。例如:

if beer.is_valid():
    instance = beer.save(commit=False)
    instance.created = datetime.now().date()
    instance.save()
Run Code Online (Sandbox Code Playgroud)